我同意答案,Kalpesh Soni
只是我想补充一点。
容器使用相同的线程来运行一对其他的 EJB 调用。一个线程只能与一个由 TM 管理的全局事务绑定。这就是@Asynchronous
bean 调用不传播事务的原因(EJB 3.2 规范,4.5.3 事务)。事务不能在更多线程上拆分,它绑定到调用者之一。
如果 bean 被标记为 CMT,则容器根据从ejb-jar.xml
描述符中获取的注释或信息来管理事务创建。容器然后能够决定 bean 方法调用是当前运行事务的一部分还是需要创建一个新事务。如前所述,大多数 Java EE 容器不支持嵌套事务。据我了解,主要原因是XAResource不支持嵌套事务(请参阅JTA 规范)。
BMT bean 用于UserTransaction
自行驱动事务管理。将现有事务传播到 BMT 应该如何工作或更好地使用它呢?如果您想开始一项新事务,UserTransaction.begin()
那么当前正在运行的事务将被暂停。这就是现在传播的工作方式。我的意思是事务没有传播,而是在 BMT bean 调用时暂停。您可以做的另一件事是推动交易。这意味着使用UserTransaction.commit()
或UserTransaction.rollback()
在传入交易中。如果您这样做,则返回的调用者将在其上下文中没有活动事务。这意味着对不同 bean 的调用可以与您的事务一起使用,而无需调用者知道并得到通知。我认为你不希望这成为可能。这就是我对背后原因的理解。
BMT 还有一个有趣的地方。如果您使用 SLSB(无状态会话 Bean),则不允许在未完成事务的情况下退出被调用的方法(请参阅EJB 3.2:8.3.3 使用 Bean-Managed Transaction Demarcation 的企业 Beans)。另一方面,SFSB(有状态会话 Bean)可以在不完成事务的情况下退出方法,并且可以在其他调用中完成。如果这样的调用发生在不同的 HTTP 会话中,那么事务将被挂起并从当前线程中获取,然后被激活并固定到新线程。
javax/transaction/xa/XAResource.html "XAResource Java EE 7 API"