何时使用Spring @Transactional(propagation = Propagation.SUPPORTS)?

ams*_*ams 18 java spring ejb java-ee

根据Spring javadoc @Transactional(propagation = Propagation.SUPPORTS)

支持当前事务,如果不存在则以非事务方式执行.类似于同名的EJB事务属性.

似乎我只能非事务性地声明方法,并且只是完成它,所以我的问题是.

  • 在什么情况下需要SUPPORTS传播?
  • 支持传播有什么意义?

任何人都可以给出支持实际有用的真实世界示例/场景吗?

Aff*_*ffe 7

我能想到的最简单的示例是将一些内容发送到JMS服务器的方法.如果您处于事务的上下文中,则希望将消息耦合到事务范围.但是如果还没有运行的事务,为什么还要打扰调用事务服务器并启动一个只执行一次性消息?

请记住,这些可以在API和实现上声明.因此,即使您将其放在那里并且不做任何操作之间的用例没有太大差异,它仍然为API作者增加了价值,以指定哪些操作可以包含在事务中,而不是可能调用的操作不参与交易的外部系统.

这当然是在JTA环境中.在事务仅限于资源本地物理数据库事务的系统中,该功能实际上没有太多实际用途.

  • 我不明白为什么分布式或不分布式会有什么区别。没有添加 NOT_SUPPORTED 的没有 SUPPORTS 的方法确实有效地支持事务。这就是这一切的全部意义。这就像为每个非最终方法添加“@PossulousOverridden”注释。无意义!Affe,你的第一段..错了?“如果没有事务正在运行”则没有事务正在运行。你的第二段也错了?同样,如果我不支持事务,我会使用 NOT_SUPPORTED。任何没有事务注释的地方都有效地“支持”。 (2认同)

dim*_*sli 5

它与readOnly=true选择操作上的事务标志形成了很好的配对,特别是在使用 ORM 时:

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果还没有用于执行选择操作的交易,请确保不要支付创建新交易的费用。

尽管如果您已经处于这个思考过程中,您甚至可能会考虑完全放弃事务方面:

public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}
Run Code Online (Sandbox Code Playgroud)