当前位置: 首页 > wzjs >正文

专业做网站排名多少钱今日最新体育新闻

专业做网站排名多少钱,今日最新体育新闻,做全国社保代理的网站,b2b电子商务网站调研报告1500字前言 在开发过程中,事务的使用是保障数据一致性的核心机制。然而,事务的隔离级别、传播行为以及框架的实现细节可能会导致一些“反直觉”的问题。 一、问题背景 1.1 业务场景 在某个基于 Spring Boot 和 MyBatis Plus 的项目中,开发人员需…

前言

在开发过程中,事务的使用是保障数据一致性的核心机制。然而,事务的隔离级别、传播行为以及框架的实现细节可能会导致一些“反直觉”的问题。

一、问题背景

1.1 业务场景

在某个基于 Spring Boot 和 MyBatis Plus 的项目中,开发人员需要实现以下功能:

  1. 更新某条记录的 score 字段;
  2. 查询该记录中 scoreNULL 的记录数量。

代码大致如下:

@Service
public class TocTopicApplyUserService {@Autowiredprivate TocTopicApplyUserMapper tocTopicApplyUserMapper;@Transactionalpublic void updateAndCount(Long topicApplyId) {// 更新操作TocTopicApplyUser user = new TocTopicApplyUser();user.setId(1L);user.setScore(85);tocTopicApplyUserMapper.updateById(user);// 查询操作long count = tocTopicApplyUserMapper.selectCount(new LambdaQueryWrapper<TocTopicApplyUser>().eq(TocTopicApplyUser::getTopicApplyId, topicApplyId).isNull(TocTopicApplyUser::getScore));}
}

1.2 问题现象

  • 更新操作执行后,score 字段确实被赋值为 85;
  • 但后续的 count 查询结果为 0,而直接在数据库客户端中执行相同的 SQL 语句却返回 1。

二、根本原因分析

2.1 事务的隔离级别

数据库事务的隔离级别决定了事务内部操作对其他事务或自身后续操作的可见性。MySQL 的默认隔离级别是 REPEATABLE READ,其特性如下:

  • 保证同一个事务内多次读取的结果一致
  • 不会看到其他事务未提交的更改
  • 即使同一事务内的更新操作已完成,后续查询也可能看不到更新后的数据(取决于数据库实现)。

在上述代码中:

  • 更新操作和查询操作处于同一个事务中;
  • 由于事务未提交,score 字段的更新尚未持久化到数据库;
  • 查询操作可能基于事务的快照(MVCC 机制)读取数据,导致无法看到更新后的值。

2.2 Spring 的事务传播行为

Spring 的 @Transactional 注解默认使用 Propagation.REQUIRED,即:

  • 如果当前存在事务,则加入该事务;
  • 事务的提交由 Spring 容器统一管理,直到方法执行完毕才会提交。

因此,更新和查询操作共享同一个事务上下文,但数据库可能因隔离级别限制,未将更新结果对后续查询可见。

2.3 MyBatis Plus 的 count 方法

MyBatis Plus 的 selectCount 方法本质上是基于数据库的 COUNT 操作:

  • 如果数据库的统计信息未更新(如 Hive 中的元数据缓存),可能导致结果异常;
  • 但在 MySQL 等支持事务的数据库中,问题更多与事务的隔离级别相关。

三、解决方案

3.1 调整事务的隔离级别

将事务的隔离级别改为 READ COMMITTED,确保更新操作对后续查询可见:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void updateAndCount(Long topicApplyId) {// 更新和查询逻辑
}
  • READ COMMITTED 的特性:
    • 每次读取操作都会看到已提交的更改;
    • 可能导致不可重复读(但能解决当前问题)。

3.2 手动提交事务

如果业务允许,可以在更新操作后手动提交事务,确保数据持久化:

@Autowired
private PlatformTransactionManager transactionManager;
private TransactionStatus transactionStatus;public void updateAndCount(Long topicApplyId) {// 开启事务transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 更新操作tocTopicApplyUserMapper.updateById(user);// 手动提交事务transactionManager.commit(transactionStatus);// 查询操作(此时在独立事务中)long count = tocTopicApplyUserMapper.selectCount(...);} catch (Exception e) {transactionManager.rollback(transactionStatus);throw e;}
}

3.3 使用 SELECT FOR UPDATE 锁定记录

在查询时加锁,强制数据库读取最新数据:

long count = tocTopicApplyUserMapper.selectCount(new LambdaQueryWrapper<TocTopicApplyUser>().eq(TocTopicApplyUser::getTopicApplyId, topicApplyId).isNull(TocTopicApplyUser::getScore).last("FOR UPDATE")
);
  • 注意FOR UPDATE 会锁定记录,需谨慎使用以避免死锁。

3.4 验证 SQL 日志

通过开启 MyBatis Plus 的 SQL 日志,确认实际执行的 SQL 与预期一致:

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

四、相关知识点总结

4.1 事务的 ACID 特性

  • 原子性(Atomicity):事务中的操作要么全部成功,要么全部失败;
  • 一致性(Consistency):事务执行前后,数据保持一致;
  • 隔离性(Isolation):多个事务并发执行时,彼此隔离;
  • 持久性(Durability):事务提交后,数据持久化到磁盘。

4.2 事务的隔离级别

隔离级别脏读不可重复读幻读适用场景
READ UNCOMMITTED无要求的高并发读写场景
READ COMMITTED大多数 OLTP 业务
REPEATABLE READ默认隔离级别(MySQL)
SERIALIZABLE严格一致性要求的场景(如金融)

4.3 Spring 事务传播行为

传播行为含义
REQUIRED如果存在事务则加入,否则新建事务(默认)
REQUIRES_NEW总是新建事务,与当前事务无关
NEVER不允许存在事务,否则抛异常
MANDATORY必须存在事务,否则抛异常

4.4 MyBatis Plus 的事务管理

  • MyBatis Plus 本身不直接管理事务,依赖 Spring 的事务机制;
  • count 方法的执行结果受数据库隔离级别和事务可见性影响;
  • 使用 @TableField 注解时,需确保字段映射正确,避免查询条件错误。

五、注意事项与最佳实践

  1. 事务隔离级别的选择

    • 根据业务需求选择合适的隔离级别,避免过度牺牲性能;
    • 在需要读取最新数据的场景中,优先使用 READ COMMITTED
  2. 事务的粒度控制

    • 避免大事务,减少锁竞争和资源占用;
    • 对于需要独立提交的逻辑,使用 REQUIRES_NEW 传播行为。
  3. SQL 日志的调试

    • 开启 SQL 日志,验证框架生成的 SQL 是否符合预期;
    • 直接在数据库客户端中执行 SQL,确认数据状态。
  4. MyBatis Plus 的字段映射

    • 使用 @TableField 明确字段与数据库列的映射关系;
    • 避免因字段名不一致导致查询条件失效。

你的问题涉及到 事务隔离级别MVCC(多版本并发控制) 的核心机制。以下是详细分析和解决方案:


问题核心:事务内更新后,查询为何看不到更新后的数据?

1.1 事务隔离级别与 MVCC 的作用
  • MySQL 默认隔离级别REPEATABLE READ
  • MVCC 机制:在 REPEATABLE READ 下,事务第一次查询时会生成一个 ReadView,后续查询复用该 ReadView。即使事务内更新了数据,只要事务未提交,新版本的数据对后续查询 不可见
1.2 为什么代码中 count 返回 0?
  • 事务内更新:你执行了 updateById(user),但事务未提交。
  • MVCC 快照:事务内的 count 查询基于事务开始时的 ReadView,无法看到事务内更新的新版本数据。
  • 数据库实际状态:事务未提交,数据仍为 NULL,但代码逻辑中因 MVCC 快照,count 查询误判为 0

关键知识点

1 事务隔离级别与 MVCC
隔离级别特性
READ COMMITTED每次查询生成新的 ReadView,能看到其他事务已提交的更改。
REPEATABLE READ第一次查询生成 ReadView,后续查询复用该视图,避免不可重复读。
2 MVCC 的 ReadView 机制
  • ReadView 包含当前活跃事务的 ID 列表。
  • 可见性规则:只有事务 ID 小于当前 ReadView 的记录才可见。
  • 事务内更新:新版本的事务 ID 会大于当前 ReadView,导致后续查询不可见。
3 Spring 事务传播行为
传播行为含义
REQUIRED加入当前事务(默认)。
REQUIRES_NEW新建事务,独立提交。
http://www.dtcms.com/wzjs/463141.html

相关文章:

  • 周口网站设计制作长尾关键词查询
  • 网站建设系统 网站自助建站系统网络运营是做什么的
  • 网站后台管理模板psdseo方式包括
  • 贵阳网站建设多少钱友情链接检测平台
  • 北京网站优化效果怎样女教师遭网课入侵直播录屏曝
  • 网站开发技术学习汕头seo优化公司
  • 邢台企业做网站费用chrome手机版
  • 做网站ftp快点tv下载安装
  • 哪个网站可以找到毕业设计链网
  • 博罗做网站百度竞价排名背后的伦理问题
  • 大气 网站模板网络口碑营销名词解释
  • 智联招聘网站多少钱做的今天的新闻摘抄
  • 住房与城乡建设部网站打不开企业如何做网络推广
  • 做公众号的网站有哪些功能seo公司怎么推广宣传
  • .net网站开发文档百度软文
  • 网站404页面优化成都网站建设企业
  • 合肥建网站公司国外域名购买
  • 有了网站怎样做公众号营销网站建设哪家好
  • wordpress ftp ubuntu深圳网站关键词优化公司
  • 招商网站建设解决方案创新驱动发展战略
  • 杭州网络公司建网站建站
  • 企业网站备案怎么做信息流广告素材网站
  • 咸宁网站制作公司福州百度推广优化排名
  • 做响应式网站的微博号网站发稿平台
  • 响应式品牌网站设计济南全网推广
  • 给网站做接口中国seo
  • 做网站骗子培训心得体会100字
  • 电脑上如何做课程视频网站百度怎么发帖做推广
  • 为什么做网站的会弄友情链接谷歌优化的网络公司
  • 做网站买什么香港服务器百度投诉中心24小时电话