3

Bean管理トランザクションを持つEJBが1つあります。

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class BmtBean {

  @Resource
  private DataSource ds1;

  @Resource
  private SessionContext sessionCtx;

  @EJB
  private CmtBean cmtBean;

  public void callCmtBean() {
    Connection conn1 = null;
    try {
      conn1 = ds1.getConnection();
      // create a PreparedStatement and execute a query
      // process result set
      while(resultSet.next()) {
        // map resultSet to an entity
        Entity entity = mapResultSetToEntity(resultSet);
        sessionCtx.getUserTransaction().begin();
        // pass an entity to another EJB,
        // that operates on a different JTA data source
        cmtBean.call(entity);
        sessionCtx.getUserTransaction().commit();
      }
    } finally {
      // release connection
    }
  }
}

そして、コンテナ管理のトランザクションを持つ別のBean:

@Singleton
@TransactionManagement(TransactionManagementType.CONTAINER)
public class CmtBean {

  @PersistenceContext
  private EntityManager em;

  @TransactionAttribute(TransactionAttributeType.MANDATORY)
  public void call(Entity entities) {
    //persist passed entities
    //em.flush()
    //em.clear();
  }

}

その前に私はを開始するので、呼び出しcmtBean#callは発生しません。ただし、が呼び出されると、次の例外がスローされます。 TransactionRequiredExceptionUserTransactionem#flush

原因:javax.resource.spi.ResourceAllocationException:接続の割り当て中にエラーが発生しました。原因:java.lang.IllegalStateException:ローカルトランザクションにはすでに1つの非XAリソースがあります:これ以上リソースを追加できません。

いくつかのEclipseLinkコードを掘り下げた後、それを呼び出すem#flush()と、から新しい接続を取得しようとしますが、取得dataSourceに失敗することがわかります。

これはバグですか、それとも予想される動作ですか?どうすればこれを修正できますか?

更新:
更新されたコード例を参照してください。

また、 XA以外の2つのJTAデータソースを使用していることを強調する必要があります。ただし、の接続BmtBeanはデフォルトでに設定されているためautocommitCmtBeanが呼び出されるまでに、トランザクションはすでにコミットされている必要があります。

4

0 に答える 0