TransactionManagementType.CONTAINER 和 TransactionManagementType.BEAN 有什么区别
因为我在我的所有 EJB 中使用 TransactionManagementType.CONTAINER,并且当使用数据库的多个实例时,它会抛出一个错误,如果我将其更改为 TransactionManagementType.BEAN 就会解决
我想知道优点和缺点是什么,以及如果我将其更改为 TransactionManagementType.BEAN 会受到怎样的影响
ERROR:
Error updating database. Cause: java.sql.SQLException: javax.resource.ResourceException:
IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.
connectionmanager.listener.TxConnectionListener@680f2be0[state=NORMAL managed
connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@7ba33a94 connection
handles=0 lastReturned=1495691675021 lastValidated=1495690817487
lastCheckedOut=1495691675018 trackByTx=false pool=org.jboss.jca.core.connectionmanager.
pool.strategy.OnePool@efd42c4 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool
@71656eec[pool=FAQuery] xaResource=LocalXAResourceImpl@4c786e85
[connectionListener=680f2be0 connectionManager=5c3b98bc warned=false
currentXid=null productName=Oracle productVersion=Oracle Database 12c
Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
jndiName=java:/FAQuery] txSync=null]
TransactionManagementType.CONTAINER
你让容器本身管理事务(容器将提交和回滚)。您可以通过使用@TransactionManagementAttribute
批注方法并指定 TransactionAttribute Type 中的一个属性来控制事务的行为(更准确地说是事务传播)。
事务管理类型.豆
您必须通过获取 UserTransaction 接口来明确自己执行事务划分(启动、提交、回滚)。
@Resource
UserTransaction ut;
public void method(){
ut.begin();
... // your business logic here
ut.commit(); // or ut.rollback();
}
请注意,在退出声明无状态和消息驱动 Bean 事务的相同方法之前,您必须提交和回滚,但对于有状态 Bean 来说,这不是必需的。
关于您的问题,BMT的优势在于交易的范围可以小于方法本身的范围,即对交易的显式控制。 您很可能会使用 CMT,BMT 仅在某些狭窄的极端情况下需要支持特定的业务逻辑。 BMT 的另一个优点或用例是,如果您需要使用扩展持久性上下文类型,该类型可以在带有状态会话 Bean 的 BMT 中得到支持。
关于您的特定问题,在没有看到任何 Bean 代码或错误消息的情况下,这可能是正在发生的事情:如果您有更多数据库,那么每个数据库及其相应的驱动程序必须能够加入现有事务,否则您将获得特定的详细错误。
如果您使用TransactionManagementType.BEAN
则需要 Bean 才能开始全新的事务。这意味着您没有加入现有事务,并且每个数据库操作彼此独立地开始和提交。
您可以通过离开TransactionManagementType.CONTAINER
并用REQUIRES_NEW
注释您的方法来实现相同的效果,当然前提是您通过相应的代理/接口调用每个 EJB。
因此,像 Bean vs CONTAINER 这样说是不正确的,而是您必须做出一些设计选择并相应地注释您的方法。
根据以下方法
之一的要求:- REQUIRES_NEW现有事务被挂起,并且该方法在全新的事务下运行
- REQUIRED 是默认行为,如果事务存在,则该方法会重用它,否则将创建该方法并在其中运行该方法