13.6.1 Bean管理的事务划分容器必须管理对企业bean的客户端调用 具有bean管理的事务划分的实例如下。当一个 客户端通过其中一个企业bean调用业务方法 客户端视图,容器挂起可能的任何事务 与客户请求相关联。
另一方面,来自独立客户端或另一个EJB的事务使用容器管理的事务传播到bean中。从CMT的角度来看,似乎使用CMT的bean还有一个重要的特性(事务传播)。
使用BMT对bean施加此限制(“交易障碍”)的原因是什么?
相关问题:
答案 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),容器设置在方法上 调用即可。插入允许容器控制 通过交易以声明方式进行交易划分 属性由开发人员设置。