Java 有@Transactional(propagation=propagation.SUPPORTS)的方法和没有@Transactional的方法有什么区别?
这两种方法的区别是什么Java 有@Transactional(propagation=propagation.SUPPORTS)的方法和没有@Transactional的方法有什么区别?,java,spring,transactional,propagation,Java,Spring,Transactional,Propagation,这两种方法的区别是什么 @Transactional(propagation = Propagation.SUPPORTS) 和一个没有@事务性的方法 例如: public class TEst { @Transactional public void methodWithTransaction1(){ methodWithSupportsTransaction(); } @Transactional public void meth
@Transactional(propagation = Propagation.SUPPORTS)
和一个没有@事务性的方法
例如:
public class TEst {
@Transactional
public void methodWithTransaction1(){
methodWithSupportsTransaction();
}
@Transactional
public void methodWithTransaction2(){
methodWithoutTransactional();
}
@Transactional(propagation = Propagation.SUPPORTS)
public void methodWithSupportsTransaction(){
}
public void methodWithoutTransactional(){
}
}
除了在关于同步的部分中指出的细微差异外,两者之间的区别在于,如果方法被注释为transactional,事务代理将拦截该方法调用,并且仅当从该方法引发运行时异常时,才会将当前事务(如果有)标记为回滚
那么,让我们举一个例子:
public class A {
@Autowired B b;
@Transactional
public void foo() {
try {
b.bar();
}
catch (RuntimeException e) {
// ignore
}
...
}
}
public class B {
// @Transactional(propagation = Propagation.SUPPORTS)
public void bar() {
throw new RuntimeException();
}
}
调用a.foo()
将在不存在事务时启动事务(需要传播)。然后将调用b.bar()并引发异常。异常被a.foo()
捕获,它继续执行,就像什么都没发生一样。在a.foo()
的末尾,事务将被成功提交
现在,让我们取消对b.bar()
上的事务性注释的注释。调用a.foo()
将在不存在事务时启动事务(需要传播)。然后将调用b.bar()并引发异常。此异常将被B周围的事务代理“截获”,它将事务标记为仅回滚。然后异常将传播到A.A.foo()
。异常被a.foo()
捕获,它继续执行,就像什么都没发生一样。在a.foo()
的末尾,事务将被提交,但该提交将失败,因为该事务已被标记为rollbackOnly。.foo()的调用者将获得TransactionSystemException。Spring支持两种类型的事务管理编程的和声明的
程序化事务管理:以这种方式,我们需要处理事务。比如说-
EntityTransaction tran = entityManager.getTransaction();
try {
tran.begin();
methodWithoutTransactional();
tran.commit();
} catch(Exception ex) {
tran.rollback();
throw ex;
}
声明性事务管理:通过这种方式,我们只需使用注释或基于xml的配置,就可以将事务管理代码从业务逻辑中分离出来。您已经在示例代码中完成了-
@Transactional
public void methodWithTransaction1(){
methodWithSupportsTransaction();
}
对于@Transactional注释,如果我们没有定义传播类型,默认情况下将应用需要的传播。您可以找到文档。可能重复[此问题][1][1]:不,这是另一个问题。好的,这是区别。但是事务日志呢?没有@Transactional的方法使用事务日志。如果我们使用@Transactional(propagation=propagation.SUPPORTS)调用方法,它将使用相同的事务日志?Spring没有事务日志。你的数据库有一个。而且您的数据库并不关心您的Spring注释。它只是作为给定事务的一部分接收SQL语句。无论是否对b.bar()进行注释,在调用a.foo()时,在a.foo()和b.bar()中完成的所有操作都将是启动的同一事务的一部分。