使用不同事务管理器的@Transactional方法调用的事务行为探究
问题
假设类A中的方法a()和类B中的方法b()均标注了@Transactional注解,但使用不同的事务管理器(tmA和tmB)。两个事务管理器对应的数据源实际连接同一数据库且使用相同凭证,且OSIV已禁用。当从方法a()中调用方法b()时,事务会延续方法a()的事务还是开启新的事务?
代码示例:
class A { private B b; @Transactional(transactionManager = "tmA") public void a() { b.b(); } } class B { @Transactional(transactionManager = "tmB") public void b() {} }
答案
这种情况会开启新的事务,具体原因如下:
- Spring的事务管理是基于事务管理器划分边界的,只要调用的方法指定了和当前事务不同的事务管理器,不管底层是否为同一数据库,Spring都会创建新事务。哪怕两个数据源完全一致,
tmA和tmB在Spring中也会被视为独立的事务控制单元。 - 执行流程上,Spring会先挂起当前由
tmA管理的事务(符合事务传播机制的前提下),然后启动tmB对应的新事务执行b()方法,等b()执行完成后,再恢复之前的tmA事务继续运行。 - 如果想让
b()复用a()的事务,必须让两个方法使用同一个事务管理器——事务管理器才是Spring判断事务上下文的核心标识,仅靠底层数据源一致无法实现事务复用。
内容的提问来源于stack exchange,提问作者Shaolin
相关产品推荐
相关产品推荐

