You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LockModeType.OPTIMISTIC与MySQL默认REPEATABLE READ是否不兼容?

Hibernate乐观锁与MySQL RR隔离级别兼容性解答

核心结论

LockModeType.OPTIMISTIC完全可以和MySQL默认的REPEATABLE READ(可重复读)隔离级别正常配合工作,你所担忧的冲突问题不存在,该误解来源于对两个组件的实现细节认知不全面。


认知偏差修正

1. MySQL RR隔离级别的读行为差异

你提到的「同一事务内一致性读复用首次快照」仅适用于普通无锁SELECT(快照读),以下操作都属于「当前读」,会直接读取最新的已提交数据,不受快照限制:

  • 加锁读:SELECT ... FOR UPDATE / SELECT ... FOR SHARE
  • 写操作:UPDATE / DELETE / INSERT

2. Hibernate乐观锁的校验逻辑

LockModeType.OPTIMISTIC的版本校验逻辑完全基于当前读实现,根本不会用到普通快照读,不存在读取旧版本的可能:

  • 若事务内修改了实体:最终执行的UPDATE语句会自动携带版本匹配条件,格式为UPDATE item SET [字段列表], version = version + 1 WHERE id = ? AND version = ?,此处UPDATE属于写操作即当前读,若其他事务已将版本更新为1,该语句影响行数为0,Hibernate会直接抛出OptimisticLockException。
  • 若事务内实体为只读:Hibernate在提交前的版本校验会发送加锁的SELECT语句SELECT version FROM item WHERE id = ? FOR SHARE,该语句属于当前读,会直接读取到最新的版本号,和实体缓存的旧版本对比不一致时就会抛出异常,根本不会复用事务开头的快照。

示例代码运行结果

你给出的代码运行时,无论事务是否修改了Item实体,都会正确捕获到其他事务的版本更新,抛出预期的OptimisticLockException,不会出现你担心的校验失效问题。

注:仅当你自定义修改了Hibernate的默认校验逻辑,改用无锁SELECT做版本校验时,才会出现校验失效的问题,官方默认实现不存在该缺陷。

内容的提问来源于stack exchange,提问作者Curry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:27:03