Glassfish にデプロイされた Java EE アプリケーションで、同じトランザクション内で 2 つの永続ユニットを使用しようとしています。
次のように、persistence.xml で 2 つの持続性ユニットが定義されています。
<persistence-unit name="BeachWater">
<jta-data-source>jdbc/BeachWater</jta-data-source>
...
<persistence-unit name="LIMS">
<jta-data-source>jdbc/BeachWaterLIMS</jta-data-source>
...
これらの永続化ユニットは、Glassfish で次のように定義した JDBC リソースと接続プールに対応します (名前とデータベース接続情報を除いて両方とも同一であるため、ここに 1 つ含めます)。
JDBC Resource:
JNDI Name: jdbc/BeachWaterLIMS
Pool Name: BEACHWATER_LIMS
Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource
Resource Type: javax.sql.ConnectionPoolDataSource
LimsServiceBean、AnalysisServiceBean、AnalysisDataTransformationServiceBean の 3 つのステートレス セッション Bean があります。
LimsServiceBean からの関連するスニペットを次に示します。
@PersistenceContext(unitName = "LIMS")
EntityManager em;
...
public ArrayList<Sample> getLatestLIMSData() {
Query q = em.createNamedQuery("Sample.findBySubTypeStatus");
return new ArrayList<Sample>(q.getResultList());
}
AnalysisServiceBean から:
@PersistenceContext(unitName = "BeachWater")
EntityManager em;
...
public ArrayList<AnalysisType> getAllAnalysisTypes() {
Query q = em.createNamedQuery("AnalysisType.findAll");
return new ArrayList<AnalysisType>(q.getResultList());
}
そして AnalysisDataTransformationServiceBean から:
@EJB
private AnalysisService analysisService;
@EJB
private LimsService limsService;
public void transformData() {
List<AnalysisType> analysisTypes = analysisService.getAllAnalysisTypes();
ArrayList<Sample> samples = limsService.getLatestLIMSData();
この limsService.getLatestLIMSData() の呼び出しにより、次の例外が発生しました。
[exec] Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b60e-fcs (12/23/2008))): oracle.toplink.essentials.exceptions.DatabaseException
[exec] Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.IllegalStateException: Local transaction already has 1 non-XA Resource: cannot add more resources.
このページ ( http://msdn.microsoft.com/en-us/library/ms378484.aspx )を参考にして、接続プールの定義を次のように変更してみました。
Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource
Glassfish 管理コンソール経由の ping は成功しますが、analysisService.getAllAnalysisTypes() を呼び出すと例外がスローされるようになりました。
Caused by: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b60e-fcs (12/23/2008))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: javax.transaction.SystemException
The resource manager is doing work outside a global transaction javax.transaction.xa.XAException: com.microsoft.sqlserver.jdbc.SQLServerException: Failed to create the XA control connection. Error: "Could not find stored procedure 'master..xp_sqljdbc_xa_init_ex'."
何か案は?