如何使用BMT将客户端UserTransaction传播到无状态会话Bean

时间:2013-07-26 16:12:06

标签: jboss transactions ejb jboss6.x bean-managed-transactions

使用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

  • 如果客户呼叫commitrollback,记录将始终写入数据库。

  • 在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?

1 个答案:

答案 0 :(得分:3)

BMT bean无法参与现有交易

来自EJB 3.1 spec.:

  13.6.1 Bean管理的事务划分

     

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