mybatis一级缓存会在执行insert/update/delete操作时立即清空,且清空发生在方法调用入口处而非事务提交后;手动clearcache()、close()、commit()或rollback()也会触发清空,以保证强一致性。

MyBatis 一级缓存会在执行任何增删改(INSERT/UPDATE/DELETE)操作时**立即清空**,且这个清空动作发生在 SQL 实际提交到数据库之前。
触发清空的增删改操作类型
以下所有方法调用都会触发一级缓存清空:
- sqlSession.insert() —— 无论参数是否为空,只要调用即清空
- sqlSession.update() —— 包括通过 Mapper 接口调用的 update 方法
- sqlSession.delete() —— 同样不依赖实际影响行数,调用即生效
清空发生的准确时机
清空不是在事务提交后,而是在执行 update() 方法入口处完成的。源码中 BaseExecutor.update() 的逻辑是:
- 先调用 clearLocalCache() 清空当前 SqlSession 的 PerpetualCache(底层是 HashMap)
- 再执行真正的数据库写操作(doUpdate)
这意味着:即使后续数据库操作因异常回滚,缓存也已经清空,不会恢复。
为什么设计成“一调就清”?
核心目的是保证强一致性:
- 避免同一个 SqlSession 中,查询结果与刚执行的写操作语义冲突(比如更新后立刻查,却返回旧值)
- 不依赖事务是否成功,因为缓存属于内存状态,无法回滚;提前清空可防止脏读风险
注意:不是只有 commit 才清空
有些开发者误以为要等 sqlSession.commit() 才会清空,其实不然:
- commit() 本身也会再次调用 clearLocalCache(),但这是二次保障,非首次触发点
- rollback() 同样会清空,防止回滚后缓存残留过期数据
- 即使没调用 commit 或 rollback,只要执行了 insert/update/delete,缓存就已失效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











