6

来自EJB 3.1 规范的引用:

13.6.1 Bean管理的事务划分

容器必须使用 bean 管理的事务划分来管理对企业 bean 实例的客户端调用,如下所示。当客户端通过企业 bean 的客户端视图之一调用业务方法时,容器将挂起任何可能与客户端请求相关联的事务。

另一方面,来自独立客户端或另一个 EJB 的事务使用容器管理的事务传播到 bean 中。从 CMT 的角度来看,使用 CMT 的 bean 似乎有一个额外的重要特性(事务传播)。

使用 BMT 对 bean 施加这种限制(“事务障碍”)的原因是什么?

相关问题:

4

4 回答 4

2

我的“猜测”是这样的

容器“看到”您已将 bean 标记为 BMT

所以在某些时候你可能会使用 UserTransaction 对象及其开始/提交/回滚等方法

而且由于 weblogic/oracle 等不支持真正的嵌套事务。容器别无选择,只能暂停当前事务以支持新事务

在 CMT 的情况下 - 因为您使用 Requires 或 RequiredNew - 容器“知道”您的意图并选择继续相同的事务,或者暂停并相应地开始一个新事务

于 2014-11-12T18:44:42.737 回答
1

我同意答案,Kalpesh Soni只是我想补充一点。

容器使用相同的线程来运行一对其他的 EJB 调用。一个线程只能与一个由 TM 管理的全局事务绑定。这就是@Asynchronousbean 调用不传播事务的原因(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"

于 2016-02-17T17:42:36.733 回答
0

我对此做了一个小的搜索,底线是 - 就像上面@kalpesh Soni 所说的那样Container knows exactly what It's doing to propagate the transaction, but leaving it to you, It's expected that you might create a scenario that causes problems due to the details of the underlying server that you use direclty- ...在这个链接中,作者描述了一个特定的场景,该场景专门针对 weblogic + 一个怪异的应用程序行为...... . 他还解释了此功能如何可用,但不是UserTransaction直接在接口中,而是在其实现之一中

于 2017-08-07T15:17:12.570 回答
-1

当您使用 BMT 时,您管理事务。您使用UserTransaction创建和提交事务。

这里的重点是UserTransaction在当前线程中创建一个事务,当您调用另一个 EJB 时,该调用将在另一个线程中执行(具有自己的 EJB 的生命周期)。

在 CMT 中,容器介入处理事务的方法调用。

3.1 UserTransaction 接口(来自 JTA 规范)

UserTransaction.begin 方法启动一个全局事务并将 该事务与调用线程相关联。事务到线程的关联由事务管理器透明地管理。

不需要支持嵌套事务。 当调用线程已与事务关联并且事务管理器实现不支持嵌套事务时,UserTransaction.begin 方法将引发 NotSupportedException。

3.2.2 完成交易

TransactionManager.commit 方法完成 当前与调用线程关联的事务。commit 方法返回后,调用线程不再关联事务。如果在线程未关联任何事务上下文时调用 commit 方法,TM 会抛出异常。

13.2.5 容器管理的分界(来自 EJB 规范)

每当客户端调用企业 bean 的业务接口(或企业 bean 的无接口视图或主接口或组件接口)上的方法时,容器就会介入方法调用。插入允许容器通过开发者设置的事务属性以声明方式控制事务划分。

于 2014-11-09T02:57:45.697 回答