Java @事务性方法调用另一个没有@Transactional anotation的方法?
我在服务类中见过一个标记为Java @事务性方法调用另一个没有@Transactional anotation的方法?,java,spring,spring-transactions,transactional,Java,Spring,Spring Transactions,Transactional,我在服务类中见过一个标记为@Transactional的方法,但它也在调用同一类中未标记为@Transactional的其他方法 这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等 没有任何注释的方法被另一个带有@Transactional注释的方法调用时的默认行为是什么?当您在事务块内调用一个没有@Transactional的方法时,父事务将继续使用新方法。它将使用来自父方法(使用@Transactional)的相同连接,并且在被调用方法(不使用@Transactio
@Transactional
的方法,但它也在调用同一类中未标记为@Transactional
的其他方法
这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等
没有任何注释的方法被另一个带有
@Transactional
注释的方法调用时的默认行为是什么?当您在事务块内调用一个没有@Transactional
的方法时,父事务将继续使用新方法。它将使用来自父方法(使用@Transactional
)的相同连接,并且在被调用方法(不使用@Transactional
)中导致的任何异常都将导致事务回滚,如事务定义中配置的那样
如果在同一实例中从具有@Transactional
的方法调用具有@Transactional
注释的方法,则被调用的方法事务行为将不会对事务产生任何影响。但是,如果您从另一个具有事务定义的方法调用具有事务定义的方法,并且它们处于不同的实例中,那么被调用方法中的代码将遵循被调用方法中给出的事务定义
您可以在的声明性事务管理一节中找到更多详细信息
Spring声明性事务模型使用AOP代理。因此,AOP代理负责创建事务。只有从实例外部调用实例中的方法时,AOP代理才会处于活动状态。@Transactional标记事务边界(开始/结束),但事务本身绑定到线程。一旦事务启动,它就会在方法调用之间传播,直到原始方法返回,事务提交/回滚 如果调用另一个具有@Transactional注释的方法,则传播取决于该注释的传播属性。
- 这是否意味着对分离方法的调用会导致应用程序打开到DB的分离连接或挂起父事务等
- 没有任何注释的方法的默认行为是什么?另一个使用@Transactional annotation的方法调用了该方法
默认传播级别(您称之为“行为”)为。如果调用的“内部”方法上有
@Transactional
注释(或通过XML进行声明性事务处理),则它将在相同的事务中执行,例如创建“nothing new”。如果内部方法没有用@Transactional注释,则内部方法将影响外部方法
如果内部方法也用@Transactional withREQUIRES\u NEW
注释,则会发生以下情况
...
@Autowired
private TestDAO testDAO;
@Autowired
private SomeBean someBean;
@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
testDAO.insertUser(user);
try{
someBean.innerMethod();
} catch(RuntimeException e){
// handle exception
}
}
@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
throw new RuntimeException("Rollback this transaction!");
}
内部方法用
REQUIRES\u NEW
注释,并引发RuntimeException,因此它将其事务设置为回滚,但不会影响外部事务。外部事务在内部事务开始时暂停,然后在内部事务结束后恢复。它们彼此独立运行,因此外部事务可以成功提交。这是spring的默认行为吗?是的。这是默认行为。@Tomasz Yes。但是还应该提到的是,在从另一个@Transactional方法调用的方法上更改事务传播不会产生任何效果。@Tomasz,这就是我所说的将遵循被调用方法中给出的事务定义。但是,如果调用来自同一个对象实例,则不会产生任何效果,因为调用不会通过负责事务维护的aop代理进行传播。@Filip,这不完全正确,如果您从不同的对象/实例调用具有@Transactional
定义的方法,则即使调用方法具有不同的@Transactional
属性,被调用的方法也将遵循其自己的事务定义。不支持且没有任何注释的子类如何?它是否继承不受支持的事务,或者他们是否按照默认要求打开了新事务?例如:f1.call(){f2()}带有f1不支持的注释和f2不支持的注释。这3个答案在某种程度上相互冲突,不确定哪一个更准确。@EricWang只想分享我今天测试了这个场景,答案是(带注释)对于这种内部调用场景,innerMethod()是最准确的。为了向初学者澄清,我非常确定innerMethod()需要位于与outerMethod()不同的bean(也称为Spring托管java对象)上。如果它们都在同一个bean上,我认为innerMethod实际上不会使用其注释中声明的事务行为。相反,它将使用outerMethod()声明中声明的内容。这是因为Spring处理AOP的方式,AOP用于它的@Transactional注释()