带@Transactional(propagation = Propagation.SUPPORTS) 的方法和不带@Transactional 的方法有什么区别?

What is the difference between a method with @Transactional(propagation = Propagation.SUPPORTS) and method without @Transactional?

方法与

有什么区别
@Transactional(propagation = Propagation.SUPPORTS)

和没有 @Transactional 的方法?

例如:

public class TEst {

    @Transactional
    public void methodWithTransaction1(){
        methodWithSupportsTransaction();
    }

    @Transactional
    public void methodWithTransaction2(){
        methodWithoutTransactional();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public void methodWithSupportsTransaction(){

    }

    public void methodWithoutTransactional(){

    }
}

除了the javadoc中关于同步的细微差别外,两者之间的区别在于,如果方法被注释为Transactional,事务代理会拦截方法调用,并将标记当前事务(如果有) , 作为 rollbackOnly 如果从该方法抛出运行时异常。

所以,让我们举个例子:

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();
    }
}

如果 none 还存在(需要传播),则调用 a.foo() 将启动事务。然后 b.bar() 将被调用并抛出异常。异常被 a.foo() 捕获,它继续执行,就好像什么也没发生一样。 a.foo()结束时,事务将提交成功。

现在让我们取消注释 b.bar() 上的事务注释。如果 none 存在(需要传播),则调用 a.foo() 将启动事务。然后 b.bar() 将被调用并抛出异常。这个异常将被 B 周围的事务代理"intercepted",它将事务标记为 rollbackOnly。然后异常将传播到 A.a.foo()。异常被 a.foo() 捕获,它继续执行,就好像什么也没发生一样。在 a.foo() 结束时,事务将被提交,但该提交将失败,因为事务已被标记为 rollbackOnly。 a.foo() 的调用者将得到一个 TransactionSystemException。

Spring 支持两种类型的事务管理 programmaticdeclarative.

程序化事务管理:这种方式的事务需要由我们来处理。例如-

EntityTransaction tran = entityManager.getTransaction(); 
try { 
    tran.begin(); 
    methodWithoutTransactional();
    tran.commit(); 
} catch(Exception ex) { 
    tran.rollback(); 
    throw ex; 
}

声明式事务管理: 以这种方式,我们可以将事务管理代码从我们的业务逻辑中分离出来,只需使用注释或基于 xml 的配置。您已经在示例代码中完成了这些操作-

@Transactional
public void methodWithTransaction1(){
    methodWithSupportsTransaction();
}

对于@Transactional注解,如果我们不定义传播类型,默认会应用PROPAGATION_REQUIRED。您可以找到文档 here.