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()中完成的所有操作都将是启动的同一事务的一部分。