news 2026/2/25 13:06:40

在一个事务里面死循环select一条数据,当我开启事务时,数据是1,每过5秒我就select一次,这个时候mybatis的一级缓存起作用了,所以不会去数据库查数据,等别的线程更新了数据表的数据,会使m

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在一个事务里面死循环select一条数据,当我开启事务时,数据是1,每过5秒我就select一次,这个时候mybatis的一级缓存起作用了,所以不会去数据库查数据,等别的线程更新了数据表的数据,会使m

这个问题涉及到 MyBatis 一级缓存、事务隔离级别和数据库的并发控制。让我详细分析一下:

1. MyBatis 一级缓存的行为

MyBatis 一级缓存(Local Cache)是SqlSession 级别​ 的缓存:

  • 在同一个 SqlSession 中执行相同的查询,MyBatis 会返回缓存中的结果

  • 默认情况下,一级缓存是开启的

2. 重要结论

不会失效,原因如下:

2.1 MyBatis 一级缓存的失效条件

MyBatis 一级缓存会在以下情况下失效:

  • 执行了 INSERT/UPDATE/DELETE 操作

  • 调用了sqlSession.clearCache()方法

  • 执行了带有flushCache="true"的查询

  • SqlSession 关闭

但是其他线程的更新不会导致当前线程的 MyBatis 一级缓存失效,因为一级缓存是 SqlSession 私有的。

3. 实际演示代码

@Service public class DemoService { @Autowired private SqlSessionFactory sqlSessionFactory; // 线程1:在事务中循环查询 public void thread1Transaction() { SqlSession sqlSession = sqlSessionFactory.openSession(TransactionIsolationLevel.READ_COMMITTED); try { for (int i = 0; i < 10; i++) { // 每次查询都会从一级缓存获取 User user = sqlSession.selectOne("com.example.mapper.UserMapper.selectById", 1L); System.out.println("Thread1 - 查询结果: " + user.getCount()); Thread.sleep(5000); // 等待5秒 } } finally { sqlSession.close(); } } // 线程2:更新数据 public void thread2Update() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.update("com.example.mapper.UserMapper.incrementCount", 1L); sqlSession.commit(); // 提交事务 } finally { sqlSession.close(); } } }

4. 解决方案

如果你希望看到其他线程的更新,有以下几种方式:

4.1 关闭 MyBatis 一级缓存(针对特定查询)

<!-- 在mapper.xml中 --> <select id="selectById" resultType="User" flushCache="true"> SELECT * FROM user WHERE id = #{id} </select>

4.2 手动清除缓存

// 在查询前清除缓存 sqlSession.clearCache(); User user = sqlSession.selectOne("com.example.mapper.UserMapper.selectById", 1L);

4.3 使用不同的 SqlSession

// 每次查询创建新的 SqlSession for (int i = 0; i < 10; i++) { try (SqlSession newSession = sqlSessionFactory.openSession()) { User user = newSession.selectOne("com.example.mapper.UserMapper.selectById", 1L); System.out.println("查询结果: " + user.getCount()); } Thread.sleep(5000); }

4.4 配置二级缓存(不推荐用于此场景)

二级缓存是 Mapper 级别的,可以被多个 SqlSession 共享,但需要考虑同步问题。

5. 事务隔离级别的影响

即使 MyBatis 每次都去数据库查询,事务隔离级别也会影响你看到的数据:

// 设置事务隔离级别为 READ_COMMITTED @Transactional(isolation = Isolation.READ_COMMITTED) public void queryInTransaction() { for (int i = 0; i < 10; i++) { User user = userMapper.selectById(1L); System.out.println("查询结果: " + user.getCount()); Thread.sleep(5000); } }

事务隔离级别

  • REPEATABLE_READ(MySQL默认):同一事务中多次读取相同数据,结果一致

  • READ_COMMITTED:可以读取到其他事务已提交的修改

6. 推荐做法

如果需要在长事务中看到其他线程的更新:

  1. 使用 READ_COMMITTED 隔离级别

  2. 关闭 MyBatis 一级缓存​ 或每次查询前清空缓存

  3. 或者使用新的 SqlSession 查询

@Transactional(isolation = Isolation.READ_COMMITTED) public void queryWithLatestData() { for (int i = 0; i < 10; i++) { // 方案1:清空缓存 clearCacheAndQuery(); // 方案2:新建SqlSession查询 queryWithNewSession(); Thread.sleep(5000); } }

核心要点:MyBatis 一级缓存只在当前 SqlSession 内有效,其他线程的操作不会使其失效。如果需要看到最新数据,需要主动绕过缓存机制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/20 20:46:52

在DevSecOps中,如何将安全测试(SAST/DAST等) 无缝集成到CI/CD流水线?

一、核心理念:安全左移,持续防护 将安全测试从传统“发布前检测”转变为开发全流程的嵌入式检查,实现“安全即代码”。 二、集成架构设计 分层安全测试策略 text CI/CD流水线安全防护链: ├── 提交前(Pre-commit) │ ├── Git Hooks:代码规范/敏感信息扫描 │…

作者头像 李华
网站建设 2026/2/16 4:48:41

腾讯云云渠道商:如何利用镜像实现跨云平台迁移?

一、引言 随着多云战略的普及&#xff0c;跨云迁移已成为企业数字化转型的关键环节。数据显示&#xff0c;超过40%​ 的企业采用多云架构&#xff0c;每年平均迁移23个应用。传统迁移方式存在停机时间长&#xff08;平均8-12小时&#xff09;、数据丢失风险&#xff08;高达15%…

作者头像 李华
网站建设 2026/2/25 8:19:29

ThinkPad风扇控制终极指南:让你的笔记本告别噪音烦恼

ThinkPad风扇控制终极指南&#xff1a;让你的笔记本告别噪音烦恼 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 还在忍受ThinkPad风扇的嗡嗡声吗&#xff1f;无论是编…

作者头像 李华
网站建设 2026/2/24 21:22:04

量化模型部署:LobeChat运行7B级别模型的可行性

量化模型部署&#xff1a;LobeChat运行7B级别模型的可行性 在个人开发者和小型团队中&#xff0c;越来越多的人希望搭建属于自己的AI对话系统——不依赖OpenAI、无需支付高昂API费用&#xff0c;还能保障数据隐私。然而&#xff0c;现实挑战摆在眼前&#xff1a;像LLaMA-2-7B或…

作者头像 李华
网站建设 2026/2/24 10:27:23

Docker本地部署AutoGPT详细教程

Docker本地部署AutoGPT详细教程 你有没有想过&#xff0c;AI 不只是被动地回答问题&#xff1f;当你说“帮我写一份关于2025年AI趋势的PPT提纲”&#xff0c;现在的 ChatGPT 会立刻动笔——但它不会主动查资料、不会判断信息是否全面、更不会回头反思&#xff1a;“我是不是漏…

作者头像 李华
网站建设 2026/2/25 8:27:09

鸣潮自动化助手:告别重复操作的终极解决方案

鸣潮自动化助手&#xff1a;告别重复操作的终极解决方案 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸上锁合成 自动肉鸽 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 还在为每日繁琐的…

作者头像 李华