为什么具有 Bean 管理事务的 EJB bean 充当"transaction barrier"?



EJB 3.1规范中的一句话:

13.6.1 Bean管理事务划分

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

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

对使用BMT的bean施加这种限制("交易障碍")的原因是什么?

相关问题:

  • JPA事务回滚失败,调用无状态bean
  • UserTransaction是如何传播的
  • 如何使用BMT将客户端UserTransaction传播到无状态会话bean中(引号已从那里复制)

我的"猜测"是这个

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

因此,在某个时刻,您可能会使用UserTransaction对象及其begin/commit/rollback等方法

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

在CMT的情况下,由于您使用了Requires或RequiredNew,容器"知道"您的意图,并选择继续相同的事务,或者相应地暂停并启动新事务。

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

容器使用相同的线程来运行一个到另一个EJB调用。一个线程只能与TM管理的一个全局事务绑定。这就是@Asynchronous bean调用不传播事务的原因(EJB 3.2规范,4.5.3事务)。事务不能在多个线程上拆分,它绑定到调用方线程。

如果bean被标记为CMT,那么容器将基于从ejb-jar.xml描述符获取的注释或信息来管理事务创建。然后,容器可以决定bean方法调用是当前正在运行的事务的一部分,还是需要创建一个新的事务。如上所述,嵌套事务在大多数JavaEE容器中都不受支持。据我所知,主要原因是XAResource不支持嵌套事务(请参阅JTA规范)。

BMTbean使用UserTransaction自行驱动事务管理。将现有事务传播到BMT应该如何工作,或者更好地使用它?如果您想用UserTransaction.begin()启动一个新事务,那么当前正在运行的事务将被挂起。现在传播就是这样运作的。我的意思是,事务不会传播,而是在BMT bean调用时挂起。您可以做的另一件事是驱动事务。这意味着在传入事务上使用UserTransaction.commit()UserTransaction.rollback()。如果您这样做,那么返回时的调用者将在其上下文中不使用活动事务的情况下工作。这意味着对另一个bean的调用可以在您的事务中工作,而不会像调用者所知道的那样得到通知。我认为您不希望这种情况发生。这就是我对背后原因的理解。

BMT还有一个有趣的地方。如果使用SLSB(无状态会话Bean),则不允许在未完成事务的情况下退出被调用的方法(请参见EJB 3.2:8.3.3使用Bean托管事务划分的企业Bean)。另一方面,SFSB(Stateful Session Bean)可以在不完成事务的情况下退出方法,并且可以在其他调用中完成。如果这样的调用发生在不同的HTTP会话中,则事务被挂起并从当前线程获取,随后被激活并固定到新线程。

javax/transaction/xa/XAResource.html";XAResource Java EE 7 API";

我对此做了一个小搜索,底线是-就像@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接口中,而是在其一个实现中

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

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

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

3.1用户事务接口(根据JTA规范)

UserTransaction.begin方法启动全局事务将事务与调用线程相关联事务到线程的关联由交易经理。

不需要对嵌套事务的支持当调用线程已经与事务相关联,并且事务管理器实现不支持嵌套交易。

3.2.2完成交易

TransactionManager.commit方法完成事务 当前与调用线程关联提交方法之后返回时,调用线程与事务没有关联。如果当线程与任何事务上下文,TM抛出异常。

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

每当客户端调用企业bean业务上的方法时界面(或在无界面视图或主界面或组件界面上对于企业bean),容器插入该方法调用。插入允许容器控制通过事务声明性地划分事务属性。

最新更新