@Transactional(传播=传播。需要)
Posted
技术标签:
【中文标题】@Transactional(传播=传播。需要)【英文标题】:@Transactional(propagation=Propagation.REQUIRED) 【发布时间】:2012-05-31 04:28:35 【问题描述】:如果有人可以解释这个注释的作用以及我们何时使用它:
@Transactional(propagation=Propagation.REQUIRED)
谢谢
【问题讨论】:
你读过这个吗? static.springsource.org/spring/docs/2.5.x/reference/… Propagation.REQUIRED是Transaction的默认传播方式,不需要显式设置。 【参考方案1】:当传播设置为 PROPAGATION_REQUIRED 时,将为应用该设置的每个方法创建一个逻辑事务范围。每个这样的逻辑事务范围都可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围。当然,在标准 PROPAGATION_REQUIRED 行为的情况下,所有这些范围都将映射到同一个物理事务。因此,在内部事务范围内设置的仅回滚标记确实会影响外部事务实际提交的机会(正如您所期望的那样)。
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html
【讨论】:
【参考方案2】:在 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
【讨论】:
【参考方案3】:要了解事务管理采用的各种事务设置和行为,例如REQUIRED
、ISOLATION
等,您必须了解事务管理本身的基础知识。
阅读Trasaction management了解更多解释。
【讨论】:
【参考方案4】:如果您需要在Spring Docs 中提供的用途之外的外行解释
考虑这段代码...
class Service
@Transactional(propagation=Propagation.REQUIRED)
public void doSomething()
// access a database using a DAO
当 doSomething() 被调用时,它知道它必须在执行之前在数据库上启动一个事务。如果此方法的调用者已经启动了一个事务,那么此方法将在当前数据库连接上使用相同的物理事务。
这个@Transactional
注释提供了一种在代码执行时告诉你的代码它必须有一个事务的方法。没有它就无法运行,因此您可以在代码中做出这样的假设,即您不会在数据库中留下不完整的数据,或者在发生异常时必须清理一些东西。
事务管理是一个相当复杂的主题,所以希望这个简化的答案会有所帮助
【讨论】:
如果有人感兴趣,我发了a similar layman's answer comparing PROPAGATION_REQUIRES_NEW, PROPAGATION_NESTED, PROPAGATION_REQUIRED 如果是使用基于代理的配置来声明和访问DAO层,进入DAO类的方法也必须用@Transactional注解。 如果您已将@Transactional
添加到服务层,则无需进一步将@Transactional
添加到该事务中调用的DAO 方法。
如果doSomething()
调用另一个没有任何@transactional 的嵌套方法,同样的事务是否也会应用于该调用方法?
是的,只要使用同一个线程来执行嵌套方法(即您没有显式创建新线程)。这是因为 Spring 事务使用 ThreadLocal 变量绑定到当前线程以上是关于@Transactional(传播=传播。需要)的主要内容,如果未能解决你的问题,请参考以下文章
@Transactional 的“REQUIRES_NEW”传播属性的真实世界用例是啥