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

Spring Boot应用默认乐观锁配置下为何出现悲观锁异常?

问题分析:为何默认乐观锁配置下出现悲观锁异常

你遇到的情况核心原因是JPA乐观锁与数据库原生锁机制并非互斥关系,二者在不同层面独立生效,具体拆解如下:

1. SQL Server默认隔离级别的锁行为

SQL Server默认隔离级别为READ COMMITTED,且默认采用基于锁的实现(而非快照隔离):

  • 执行UPDATE语句时,SQL Server会先对目标行加排他锁(X锁),该锁会持有到事务提交或回滚后才释放。
  • 当多个并发事务更新同一User行时,后执行的事务会等待前序事务释放排他锁。如果等待时间超过数据库锁超时阈值(SQL Server默认是5秒),就会抛出CannotAcquireLockException(属于悲观锁异常)。

2. 乐观锁的生效时机与数据库锁的优先级

JPA乐观锁是应用层面的版本校验逻辑,仅在事务提交阶段触发:

  • JPA会生成带版本条件的更新SQL:UPDATE user SET ..., version = version+1 WHERE id = ? AND version = ?
  • 但执行这条SQL前,数据库必须先获取目标行的排他锁。若此时该行被其他事务锁定,数据库层面的锁等待会优先触发,导致悲观锁异常;只有当锁获取成功,但版本校验不通过(更新行数为0)时,才会触发JPA的ObjectOptimisticLockingFailureException。

3. 事务时长加剧锁竞争

如果你的服务方法中,创建Order与更新User之间存在耗时操作(比如远程调用、复杂计算),会拉长事务持有锁的时间,大幅提升并发场景下的锁冲突概率,更容易触发悲观锁异常。

可参考的解决方向

  • 调整SQL Server隔离级别:开启READ COMMITTED SNAPSHOT,让读操作使用快照而非共享锁,减少锁竞争。
  • 缩短事务时长:将非核心操作(如日志记录、非关联第三方调用)移出事务范围。
  • 优化更新逻辑:通过异步队列等方式,降低同一行数据的并发更新频率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:13:33