Spring事务场景:三段lockData流程是否同属事务?能否在A1中查看C1行锁?
关于Spring事务与行锁的两个疑问
问题描述
我有以下两个疑问:
- 三段
lockData流程是否同属一个事务? - 当流程回到A1类时,能否查看C1类在employee表上添加的行锁?
当前调用流程:A1实例 → B1实例 → C1实例
对应的代码如下:
class A1 { @Transactional(propagation = Propagation.REQUIRES_NEW) public void lockData(){ B1 classBObj = ctx.getBean("B1"); boolean locked = classBObj.lockData(); //检查employee表上的锁是否仍存在 } } class B1 { @Transactional(propagation = Propagation.REQUIRED) public void lockData(){ C1 classCObj = ctx.getBean("C1"); classCObj.lockData(); return true; } } class C1 { public void lockData(){ executeQuery("select * from employee where emp_id=1 for update"); return true; } }
解答
1. 三个lockData方法是否同属一个事务?
是的,三者完全处于同一个事务中,具体依据Spring事务传播机制的规则:
A1.lockData的REQUIRES_NEW传播机制:无论当前是否存在活跃事务,都会强制创建一个全新的独立事务,这是整个调用链的事务起点。B1.lockData的REQUIRED传播机制:这是Spring默认的事务传播行为,它会优先复用当前已存在的活跃事务——这里就是A1创建的那个新事务,所以B1不会新建事务,直接加入到A1的事务中。C1.lockData没有事务注解:在Spring的事务管理逻辑中,无事务注解的方法会继承调用方的事务上下文,也就是B1所在的A1的事务,因此它的执行也属于同一个事务。
2. 回到A1后能否查看C1添加的行锁?
可以,而且此时行锁仍然有效:
- 数据库的行锁是和事务绑定的,
select ... for update加的行锁会被当前事务持有,直到事务提交或回滚。当流程回到A1的lockData方法时,整个事务还未结束(方法尚未执行完毕,事务还没触发提交/回滚),所以行锁依然存在。 - 如果你要验证锁的存在,可以在A1的检查逻辑中执行
select * from employee where emp_id=1 for update:因为是同一个事务持有锁,这个查询不会被阻塞,会直接返回数据,这就证明锁仍在生效;如果是其他独立事务执行这条语句,就会被阻塞直到当前事务结束。
内容的提问来源于stack exchange,提问作者Shrutika B.K.
相关产品推荐
相关产品推荐

