Java 何时使用Spring@Transactional(传播=传播.支持)?

Java 何时使用Spring@Transactional(传播=传播.支持)?,java,spring,jakarta-ee,ejb,Java,Spring,Jakarta Ee,Ejb,根据SpringJavadoc@Transactional(propagation=propagation.SUPPORTS) 支持当前事务,如果没有,则以非事务方式执行 存在。类似于同名的EJB事务属性 似乎我可以将方法声明为非事务性的,然后就可以使用它了,所以我的问题是 在哪些情况下需要支持传播 支持传播的意义是什么 有谁能给出一个支持实际有用的真实示例/场景吗?我能想到的最简单的示例是向JMS服务器发送一些内容的方法。如果您处于事务上下文中,则希望将消息耦合到事务范围。但是如果还没有事

根据SpringJavadoc
@Transactional(propagation=propagation.SUPPORTS)

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

似乎我可以将方法声明为非事务性的,然后就可以使用它了,所以我的问题是

  • 在哪些情况下需要支持传播
  • 支持传播的意义是什么

有谁能给出一个支持实际有用的真实示例/场景吗?

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

请记住,这些可以在API和实现上声明。因此,即使将其放在那里和不放在那里对您的用例没有太大区别,它仍然为API作者指定哪些操作可以包含在事务中增加了价值,而不是调用不参与事务的外部系统的操作


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

它与选择操作上的
readOnly=true
事务标志是一对很好的组合,尤其是在使用ORM时:

@Transactional(readOnly = true, propagation=Propagation.SUPPORTS)
public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}
在这种情况下,若还并没有一个事务只用于执行select操作,那个么请确保不要支付创建新事务的费用

虽然你已经在那个思维过程中了,你甚至可以考虑把交易方面都抛弃在一起:

public Pojo findPojo(long pojoId) throws Exception {
   return em.find(Pojo.class, pojoId);
}
根据此问题,您不应使用传播设置只读事务。支持:


这一变化是否真的会提高性能还不清楚。这有多个方面。首先,这篇链接文章过时了,而且有着令人难以置信的缺陷,因为它大大简化了事情。如果你愿意的话,我可以详细谈谈,但我现在就不谈了。这里有很多因素影响执行性能。如果没有正在进行的事务,readOnly标志既不会传播到JDBC驱动程序(这会导致许多数据库的优化未被应用),也不会应用Spring的JPA资源管理代码中的优化,例如显式关闭刷新,如果应用,它可以在读取大量数据的情况下显著提高性能。

在您给出的JMS示例中,如果没有tx,但是jms会话/生产者是共享的,那么作为tx的一部分发送的消息。我想分布式tx是唯一一个支持有用的地方。我认为,如果您有不支持的实例并且想要区分,它在非分布式设置中作为API标记仍然是有用的。但你是对的,从实现的角度来看,如果tx不是分布式的,那么它和什么都不放在那里并没有太大区别。我不明白为什么分布式和非分布式会有任何区别。如果一个没有支持的方法没有添加不支持的,那么它确实有效地支持事务。这就是所有这些的要点。这就像给每个非final方法添加一个“@possiblyOverrided”注释。无意义的阿菲,你的第一段。。这是错的吗?“如果没有事务运行”,则没有事务运行。你的第二段,也错了吗?同样,如果我不支持事务,我将使用“不支持”。任何没有事务注释的地方都可以有效地“支持”。我不确定你想要的是什么样的回应,对一个关于一个18年前的API的7年前的答案发表评论,这个API似乎是一个基于现代感性的愚蠢设计。。。。对它实际上“什么都不做”。。。是的,20年前的Sun工程师与今天的谷歌和facebook工程师有着不同的设计理念?如果我今天回答这个问题,我可能会写这样的话:“这就是我们在2002年推出的方式,那种对UML值的‘完整性’感到兴奋的人,即使设置实际上是不允许的。”那么…它真的值得通过ORM框架(例如MyBatis)将@Transactional注释用于在本地数据库中进行选择吗?通过“抛弃事务方面”,这与使用@NotTransactional相同吗?如果某个对象没有事务方面,或者是@NotTransactional,并且从事务中调用它,会发生什么?e、 g.如果事务性方法A向DB写入了一些内容,然后调用NotTransactional方法be,它也会写入一些内容,然后eiter A或B抛出一个未经检查的异常,该异常会被回滚?我仍然看不到支持与不支持之间的区别。我认为API设计人员只是简单地说,他们过于沉迷于注释。也许将来的某一天,我们会扭转这一恶习,按照上帝的意愿重新开始真正的面向对象编程。Heva看看这个答案: