使用CMT的这种情况正在发挥作用:
带有CMT的无状态会话bean,一个用@TransactionAttribute(TransactionAttributeType.MANDATORY)
注释的方法。在此方法中,使用XA数据源和普通JDBC将记录写入RDBMS。
独立客户端(单独的JVM,命令行Java应用程序)从应用程序服务器获取UserTransaction
(通过JNDI查找),
启动事务,并调用EJB。
如果客户端提交UserTransaction
,则记录将写入数据库。
UserTransaction
,则记录不会写入数据库。在PostgreSql日志文件中,可以看到准备好的事务与BEGIN,COMMIT或ROLLBACK
如果客户端在调用EJB之前没有启动事务,则抛出javax.ejb.EJBTransactionRequiredException
(按预期,TransactionAttributeType.MANDATORY
)。
现在我从CMT切换到BMT
同样,如果客户端在调用EJB之前没有启动事务,则抛出javax.ejb.EJBTransactionRequiredException
(如预期的那样,TransactionAttributeType.MANDATORY)。
如果我致电sessionContext.getUserTransaction().getStatus()
,则会始终报告Status.STATUS_NO_TRANSACTION
。
如果客户呼叫commit
或rollback
,记录将始终写入数据库。
在PostgreSql日志文件中,没有准备好的事务,只有普通的插入命令。
EJB的来源:
@Remote(DemoIfc.class)
@Stateless(name = "DemoBmt")
@TransactionManagement(TransactionManagementType.BEAN)
public class DemoBmt implements DemoIfc {
@Resource
private SessionContext sessionContext;
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public String ping(final String s) throws SystemException {
try {
System.out.println("TX: status: "
+ this.sessionContext.getUserTransaction().getStatus());
} catch (Exception e) {
System.out.println("TX: status: " + e.getMessage());
}
try {
writeIntoDb();
if (s.startsWith("crash")) {
throw new SystemException("Simulated crash");
}
return s.toUpperCase();
} catch (NamingException e) {
throw new SystemException(e.getMessage());
} catch (SQLException e) {
throw new SystemException(e.getMessage());
}
}
}
客户来源:
final UserTransaction ut = (UserTransaction) initialContext
.lookup("UserTransaction");
try {
ut.begin();
System.out.println(demo.ping("crash: DemoBmt with UT"));
ut.commit();
} catch (Exception ex) {
System.out.println("Expected rollback");
ut.rollback();
}
我正在使用JBoss 6.0.0 final。
如何使用BMT将客户端UserTransaction正确传播到EJB?
答案 0 :(得分:3)
BMT bean无法参与现有交易
13.6.1 Bean管理的事务划分容器必须管理对企业bean的客户端调用 具有bean管理的事务划分的实例如下。当一个 客户端通过其中一个企业bean调用业务方法 客户端视图,容器挂起可能的任何事务 与客户请求相关联....