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

Spring中被挂起的@Transactional方法是否会阻塞持有数据库资源?

问题1:outer方法是否会在inner提交前持有用户资源的锁

是的,这个结论完全成立。

在你给出的Spring声明式事务逻辑中,outerMethod配置的是REQUIRED传播级别,执行testDAO.updateUser(user)时,会在当前事务中拿到对应用户行的排他锁(以最常用的InnoDB存储引擎为例)。而数据库事务的排他锁只有在当前事务提交或回滚时才会释放。

当调用someBean.innerMethod()时,因为innerMethod配置了REQUIRES_NEW传播级别,Spring会先将outerMethod的现有事务挂起,开启一个全新的独立事务执行innerMethod的逻辑,直到innerMethod的新事务提交完成后,才会恢复outerMethod的原有事务继续执行。
也就是说outerMethod的事务提交时机,一定是在innerMethod执行完成之后,所以updateUser拿到的锁,会贯穿整个innerMethod的执行周期,直到outerMethod最终提交才会释放。


问题2:是否可以类比为两个数据库控制台顺序执行

这个类比完全准确,执行流程和你列的步骤完全一致:

-- 第一个控制台(对应outer的原有事务)
1. begin;
2. update user set ...; -- 拿到对应用户行的锁,暂不释放

-- 第二个控制台(对应inner的REQUIRES_NEW新事务)
3. begin;
4. -- 执行inner中的所有业务逻辑
5. commit; -- inner事务提交完成

-- 回到第一个控制台
6. commit; -- 此时才释放update拿到的用户行锁

额外注意事项

这种写法有非常高的性能风险:

  • 如果innerMethod执行逻辑耗时较长,会导致用户行锁被长时间持有,大量请求操作同一用户时会直接产生大量锁等待,数据库吞吐骤降
  • 如果innerMethod中也需要修改同一个用户的数据,会直接触发死锁:outer事务持有锁等待inner执行完成,inner的新事务等待outer释放锁,两个事务互相等待永远无法结束

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:27:00