@Transactional(propagation=Propagation.REQUIRED)

113

如果有人能解释一下这个注解的作用以及什么时候我们会使用它:

@Transactional(propagation=Propagation.REQUIRED)

感谢


3
你读过这个吗?http://static.springsource.org/spring/docs/2.5.x/reference/transaction.html#tx-propagation - Brad
3
Propagation.REQUIRED 是事务的默认传播模式,因此您不需要显式设置它。 - tibtof
4个回答

179

如果你需要一个非专业人士的解释,来解释在Spring文档中提供的使用方法之外的内容。

考虑以下代码...

class Service {
    @Transactional(propagation=Propagation.REQUIRED)
    public void doSomething() {
        // access a database using a DAO
    }
}

当调用 doSomething() 时,它知道在执行之前必须在数据库上启动一个事务。如果调用此方法的调用方已经开始了一个事务,则该方法将在当前数据库连接上使用相同的 物理 事务。

这个 @Transactional 注释提供了一种告诉代码在执行时必须有一个事务的方法。如果没有事务,则代码不会运行,所以您可以在代码中做出这样的假设:您不会留下不完整的数据在数据库中,或者必须清理一些异常情况下的内容。

事务管理是一个相当复杂的主题,因此希望这个简化的答案能有所帮助。


如果使用基于代理的配置来声明和访问DAO层,则DAO类中的方法也必须带有@Transactional注释。 - TomasMolina
如果您已经在服务层添加了@Transactional,则不需要在该事务中调用的DAO方法中再次添加@Transactional - Brad
如果doSomething()调用了另一个没有@transactional注释的嵌套方法,那么这个事务是否也会应用于调用方法? - thisarattr
只要使用相同的线程来执行嵌套方法(即不明确创建新的线程),就可以实现此操作。这是因为Spring事务使用ThreadLocal变量绑定到当前线程。 - Brad

71
当传播设置为PROPAGATION_REQUIRED时,对应的每个方法都会创建一个逻辑事务范围。每个这样的逻辑事务范围可以单独确定回滚状态,外部事务范围与内部事务范围是逻辑上独立的。当然,在标准PROPAGATION_REQUIRED行为的情况下,所有这些范围都将映射到同一个物理事务。因此,在内部事务范围中设置的回滚标记确实会影响外部事务实际提交的机会(正如您所期望的那样)。

enter image description here

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html


16
在Spring应用程序中,如果你使用<tx:annotation-driven/> 启用了基于注解的事务支持,并在任何类/方法上使用@Transactional(propagation=Propagation.REQUIRED)进行标注,则Spring框架会启动一个事务并执行该方法,最后提交事务。如果发生任何RuntimeException异常,则事务将回滚。
实际上,propagation=Propagation.REQUIRED是默认传播级别,你不需要明确指定它。
更多信息请参见:http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations

5
要理解在事务管理中采用的各种事务设置和行为,例如REQUIREDISOLATION等,必须先理解事务管理的基础知识。请阅读Transaction management了解更多解释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接