使用@Transactional(propagation = Propagation.SUPPORTS)的方法和没有@Transactional的方法有什么区别?

时间:2015-07-26 06:12:06

标签: java spring transactional propagation

方法与

有什么区别
@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(){

    }
}

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:0)

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 注释,如果我们不定义传播类型,默认情况下将应用 PROPAGATION_REQUIRED 。您可以找到文档here