【Mytais系列】Update语句执行流程
以下是通过 时序图 和 文字说明 详细描述的 MyBatis 执行 UPDATE/INSERT/DELETE
语句的完整流程,包括缓存清理、事务提交和数据库操作的各个环节:
时序图(Sequence Diagram)
详细执行流程解析
1. 客户端发起更新请求
- 客户端调用
SqlSession
的更新方法(如update
),传入 SQL 语句标识(如updateUser
)和参数(如User
对象)。
2. 一级缓存清理(BaseExecutor)
- 立即清理一级缓存:
MyBatis 在执行UPDATE/INSERT/DELETE
时,会直接清空当前SqlSession
的一级缓存(localCache
),确保后续查询能获取最新数据。
3. 数据库操作
- 3.1 创建 PreparedStatement
StatementHandler
创建PreparedStatement
对象,并处理动态 SQL(如<if>
标签)。 - 3.2 参数绑定
ParameterHandler
将参数对象(如User
)绑定到 SQL 占位符(?
)。 - 3.3 执行 SQL
通过 JDBC 驱动执行 SQL,数据库返回影响行数。
4. 二级缓存清理(事务提交时生效)
- 延迟清理二级缓存:
MyBatis 在事务提交(commit()
)或关闭SqlSession
时,才会清理该Mapper
对应的二级缓存。
-
- 若事务未提交,二级缓存不会立即清理(避免中间状态污染缓存)。
- 若事务提交,清理所有关联的二级缓存(通过
<cache-ref>
或Mapper
映射关系)。
5. 事务提交
- 默认情况下,MyBatis 不会自动提交事务。需显式调用
sqlSession.commit()
,此时:
-
- 提交数据库事务(通过
TransactionManager
)。 - 清理关联的二级缓存(若配置了
<cache/>
)。
- 提交数据库事务(通过
关键组件作用
组件 | 职责 |
| 用户操作入口,封装会话状态和事务控制。 |
| 执行器,负责缓存清理和 SQL 执行( |
| 处理 SQL 语句(创建 |
| 绑定 SQL 参数(支持复杂对象和动态参数)。 |
| 管理事务提交/回滚(如 |
缓存清理规则
- 一级缓存:
-
- 立即清理:所有 DML 操作执行后,立即清空当前
SqlSession
的一级缓存。 - 作用范围:仅当前会话。
- 立即清理:所有 DML 操作执行后,立即清空当前
- 二级缓存:
-
- 延迟清理:在事务提交或会话关闭时,清理关联的
Mapper
二级缓存。 - 作用范围:全局(跨会话共享)。
- 延迟清理:在事务提交或会话关闭时,清理关联的
示例场景
场景 1:更新后未提交事务
// 执行更新(清理一级缓存,二级缓存未清理)
sqlSession.update("updateUser", user);// 同一会话查询(查数据库,因一级缓存已清空)
User updatedUser = sqlSession.selectOne("selectUserById", 1);// 其他会话查询(命中旧二级缓存,数据不一致)
场景 2:更新后提交事务
// 执行更新(清理一级缓存)
sqlSession.update("updateUser", user);// 提交事务(清理二级缓存)
sqlSession.commit();// 其他会话查询(二级缓存已清空,查数据库)
SqlSession newSession = sqlSessionFactory.openSession();
User user = newSession.selectOne("selectUserById", 1);
注意事项
- 事务边界控制:
-
- 务必显式调用
commit()
或rollback()
,否则数据库修改和二级缓存清理不会生效。
- 务必显式调用
- 二级缓存关联性:
-
- 若多个
Mapper
共享缓存(通过<cache-ref>
),更新任意关联Mapper
均会触发缓存清理。
- 若多个
- 批量操作优化:
-
- 使用
BatchExecutor
可批量执行 DML 语句,减少 JDBC 交互次数。
- 使用
- 主键生成策略:
-
INSERT
操作可通过<selectKey>
或useGeneratedKeys
获取数据库生成的主键。
总结
MyBatis 执行 UPDATE/INSERT/DELETE
的流程核心是 数据一致性保证:
- 立即清理一级缓存,避免当前会话后续查询读到脏数据。
- 延迟清理二级缓存,依赖事务提交机制确保全局缓存一致性。
- 事务提交是关键,未提交的修改不会影响二级缓存或数据库持久化。
理解这一流程可帮助开发者合理设计事务边界和缓存策略,避免因缓存未及时清理导致的数据不一致问题。