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

org.hibernate.PessimisticLockException异常成因与锁类型问询

事务锁冲突问题分析与解答

代码流程

//Service Class A
@Transactional
mainMethod() {

    // some business logic
    methodA()
    ..
}

// Component class helperA
@Transactional(propagation = Propagation.REQUIRES_NEW)
methodA() {

    // some business logic
    addLogMethod()
}

// Component class helperLog
addLogMethod(){
    // create the log entity
    repo.save(entity)
}

问题描述

执行addLogMethod时触发org.hibernate.PessimisticLockException: could not execute statement异常,抛出点为repo.save(entity)。根因指向外事务施加的悲观锁,而外事务因内部事务启动已被挂起。

现状分析

待保存的日志实体不属于外事务,但该实体与外事务关联的表存在外键关系,这种关联似乎阻止新事务获取对应表的控制权。已验证内部事务可读取外事务锁定的表数据,但不解为何保存日志实体时触发异常——若为Pessimistic.WRITE锁,读取操作应被禁止。

疑问

已知合并事务可解决问题,但想明确:

  • 外事务获取的是什么类型的锁?
  • 为何会阻止关联外键的日志表新增记录?

解答

1. 外事务的锁类型

外事务持有的是**Pessimistic.WRITE(悲观写锁)**,你能读取锁定数据是因为主流数据库的悲观写锁遵循「共享读、排他写」规则:持有写锁的事务允许其他事务读取数据,仅禁止其他事务修改数据或加写锁,这和你验证的读取正常的现象完全匹配。

2. 阻止日志表新增的原因

问题核心在于外键约束的检查机制:
当内部事务插入日志实体时,数据库必须验证日志实体关联的外键记录是否存在(外键约束的强制要求)。此时外事务已经对关联的主表记录加了Pessimistic.WRITE锁,而外事务因内部事务启动被挂起,锁无法及时释放。内部事务的外键检查操作需要访问被锁定的主表记录,却无法获取所需的锁资源,最终触发锁超时或直接抛出PessimisticLockException。

简单来说:不是日志表被锁,而是插入日志时要验证的主表记录被外事务锁定,外事务挂起导致锁无法释放,内部事务的验证操作被阻塞,进而报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:04:50