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
は発生しません。ただし、が呼び出されると、次の例外がスローされます。 TransactionRequiredException
UserTransaction
em#flush
原因:javax.resource.spi.ResourceAllocationException:接続の割り当て中にエラーが発生しました。原因:java.lang.IllegalStateException:ローカルトランザクションにはすでに1つの非XAリソースがあります:これ以上リソースを追加できません。
いくつかのEclipseLinkコードを掘り下げた後、それを呼び出すem#flush()
と、から新しい接続を取得しようとしますが、取得dataSource
に失敗することがわかります。
これはバグですか、それとも予想される動作ですか?どうすればこれを修正できますか?
更新:
更新されたコード例を参照してください。
また、 XA以外の2つのJTAデータソースを使用していることを強調する必要があります。ただし、の接続BmtBean
はデフォルトでに設定されているためautocommit
、CmtBean
が呼び出されるまでに、トランザクションはすでにコミットされている必要があります。