为什么使用bean管理的事务的EJB bean充当“事务障碍”?

时间:2013-07-27 13:08:17

标签: java-ee transactions ejb bean-managed-transactions

来自EJB 3.1 specification

的引用
  13.6.1 Bean管理的事务划分

     

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

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

使用BMT对bean施加此限制(“交易障碍”)的原因是什么?

相关问题:

4 个答案:

答案 0 :(得分:2)

我的“猜测”就是这个

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

所以在某些时候你可能会使用UserTransaction对象及其begin / commit / rollback等方法

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

对于CMT - 由于您使用Requires或RequiredNew - 容器“知道”您的意图并选择继续相同的交易,或相应地暂停并开始新的交易

答案 1 :(得分:1)

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

Container使用相同的线程来运行一个到其他EJB调用。线程只能与TM管理的一个全局事务绑定。 这就是@Asynchronous bean调用不传播事务(EJB 3.2规范,4.5.3事务)的原因。交易不能分散在更多线程上,而是与调用者绑定。

如果bean被标记为CMT,则容器根据从ejb-jar.xml描述符获取的注释或信息来管理事务创建。然后,Container可以决定bean方法调用是否是当前正在运行的事务的一部分,或者是否需要创建新的事务。如上所述,大多数Java EE容器都不支持嵌套事务。据我所知,主要原因是XAResource不支持嵌套事务(参见JTA spec)。

BMT bean使用UserTransaction来自行驱动事务管理。如何将现有交易传播到BMT应该如何工作或者更好?如果您想使用UserTransaction.begin()开始新的交易,那么当前正在运行的交易将被暂停。这就是现在传播的方式。我的意思是事务没有传播,但在BMT bean调用时暂停。 你可以做的另一件事是驱动交易。这意味着对传入的事务使用UserTransaction.commit()UserTransaction.rollback()。如果这样做,那么返回时调用者将在其上下文中没有活动事务。这意味着对不同bean的调用可以在您没有调用者知道的情况下处理您的事务并得到通知。我想你不希望这是可能的。这是我对背后原因的理解。

BMT还有另一个有趣的事情。如果使用SLSB(无状态会话Bean),则不允许在不完成事务的情况下退出被调用的方法(请参阅EJB 3.2: 8.3.3 Enterprise Beans Using Bean-Managed Transaction Demarcation)。另一方面,SFSB(有状态会话Bean)可以在不完成事务的情况下退出方法,并且可以在其他调用中完成。如果发生此类呼叫,在不同的HTTP会话中,事务被挂起并从当前线程中获取,然后激活并固定到新线程。

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

答案 2 :(得分: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 ...在this link中,作者描述了一个出现问题的特定场景特别是与weblogic +一个怪异的应用程序行为....他还说明了这个功能是如何可用的,但不是直接在UserTransaction接口中,而是在其中一个实现中

答案 3 :(得分:-1)

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

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

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

3.1 UserTransaction接口(来自JTA规范)

  

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

     

不需要支持嵌套转移。   UserTransaction.begin方法何时抛出NotSupportedException   调用线程已经与事务相关联   事务管理器实现不支持嵌套   交易。

     

3.2.2完成交易

     

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

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

  

每当客户端调用企业bean业务的方法时   接口(或无接口视图或家庭或组件接口   一个企业bean),容器设置在方法上   调用即可。插入允许容器控制   通过交易以声明方式进行交易划分   属性由开发人员设置。

相关问题