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

READ-COMMITTED事务隔离级别下的先插后查问题记录

问题:

这段代码count输出1,response输出null,为什么?已知查询条件匹配,数据库连接的同一个(测试环境),没有读写分离读(主库写,从库读,SHOW SLAVE STATUS),不存在主从同步延迟问题。

SELECT @@transaction_isolation查出的事务隔离级别是READ-COMMITTED。

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);

MyBean dto = new MyBean();
dto.setName("test");
Integer count = writeDao.insert(dto);
log.info(count);
MyBean response = readDao.selectByName("test");
log.info(response);

transactionManager.commit(status);

解析:

在 READ-COMMITTED 隔离级别下,数据库的行为是:

  • 只能读取已提交的数据,防止脏读(读取未提交的数据)。

  • 在一个事务中,未提交的数据对当前事务的后续查询不可见,即使是同一个事务中的操作。

代码逻辑

  • 事务开始:transactionManager.getTransaction(def) 创建一个新事务(PROPAGATION_REQUIRED)。

  • 插入数据:writeDao.insert(dto) 执行插入操作,count 输出 1,说明插入成功。但此时数据尚未提交。

  • 查询数据:readDao.selectByName("test")执行查询。由于事务尚未提交,且隔离级别是 READ-COMMITTED,插入的数据对当前查询不可见,因此返回 null。

  • 提交事务:transactionManager.commit(status) 提交事务,插入的数据才对其他事务可见。

可能的原因:

1.在 READ-COMMITTED 隔离级别下,未提交的数据(即 insert 插入的数据)在事务提交之前不可见。因此,selectByName 查询不到刚插入的数据,返回 null 是符合预期的行为。 

解决:

(1) 在同一事务中直接查询(不依赖隔离级别)

如果必须在同一事务中查询,可以直接通过主键或插入后返回的自增 ID 查询记录,而不是依赖 selectByName 的逻辑。

 Long insertedId = dto.getId(); // 需确保 insert 方法返回 ID
 MyBean response = readDao.selectById(insertedId);

直接通过 ID 查询记录,可以绕过隔离级别的影响(因为同一事务中的插入操作对后续查询可见)

(2) 降低隔离级别(谨慎操作)

可以将隔离级别临时降低到 READ-UNCOMMITTED,这样未提交的数据对当前事务可见。但这会导致脏读问题(读取未提交的数据,如果事务回滚,读取的数据可能是错误的),不推荐在生产环境中使用。

设置隔离级别(MySQL 示例):

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

相关文章:

  • 谷歌Gemini 2.0 Flash放出原生多模态图像生成功能:支持多轮对话式实时编辑,附最新尝鲜方式
  • 【算法】DFS、BFS、拓扑排序
  • Unity引擎架构介绍及代码示例
  • 网络安全设备系统集成方案 系统集成和网络安全
  • petalinux环境下给linux-xlnx源码打补丁
  • 重学vue3:vue3组件通信的几种方法
  • OpenAI新工具助力开发者:AI智能体自动任务创建的艺术
  • 基于DeepSeek的智能数据分析和自动化处理系统:引领BI行业新变革
  • redis的持久化
  • 详解 C++ 左值和右值对象 左值引用和右值引用
  • RabbitMQ报错:Shutdown Signal channel error; protocol method
  • 微信小程序-实现锚点跳转,页面加载后自动跳转、点击跳转到指定位置
  • ubuntu 设置允许root远程登录
  • c语言笔记 静态函数和递归函数
  • 基于PyTorch通信算子的分布式训练阻塞定位方法
  • emacs使用mongosh的方便工具发布
  • 为什么 JPA 可以通过 findByNameContaining 自动生成 SQL 语句?
  • The First项目报告:重塑 DeFi 流动性的革新者,ELX 即将登陆 The First
  • Vue 系列之:路由
  • 玩转python:通俗易懂掌握高级数据结构:collections模块之namedtuple
  • 新手写作网站/推广方式营销方案
  • 西安做网站公司哪家好/游戏推广文案
  • 唐山建设集团下岗职工网站/营销型网站建设实训总结
  • 网站垃圾代码检查工具/经典软文
  • 出国越南做网站8000保底/seo关键词怎么填
  • 劫持网站挂广告是个人做的吗/新业务在线软件下载