EJB3 - à l'aide de 2 unités de persistance au sein d'une transaction (à l'Exception des Locaux de la transaction a déjà 1 non-XA de Ressources)

Je suis en train d'utiliser 2 unités de persistance dans la même transaction dans une application Java EE déployé sur Glassfish.

Les 2 unités de persistance sont définis dans persistence.xml comme suit:

<persistence-unit name="BeachWater">
<jta-data-source>jdbc/BeachWater</jta-data-source>
...
<persistence-unit name="LIMS">
<jta-data-source>jdbc/BeachWaterLIMS</jta-data-source>
...

Ces unités de persistance correspondent à des ressources JDBC et les pools de connexions qui j'avais défini dans Glassfish comme suit (inclure ici que les deux sont identiques, hormis les noms & connexion de base de données info):

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

Il y a 3 beans de session sans état, LimsServiceBean, AnalysisServiceBean et AnalysisDataTransformationServicebean.

Voici les extraits de LimsServiceBean:

@PersistenceContext(unitName = "LIMS")
EntityManager em;
...
public ArrayList<Sample> getLatestLIMSData() {
    Query q = em.createNamedQuery("Sample.findBySubTypeStatus");
    return new ArrayList<Sample>(q.getResultList());
}

De AnalysisServiceBean:

@PersistenceContext(unitName = "BeachWater")
EntityManager em;
...
public ArrayList<AnalysisType> getAllAnalysisTypes() {
    Query q = em.createNamedQuery("AnalysisType.findAll");
    return new ArrayList<AnalysisType>(q.getResultList());
}

Et de AnalysisDataTransformationServicebean:

@EJB
private AnalysisService analysisService;

@EJB
private LimsService limsService;

public void transformData() {
    List<AnalysisType> analysisTypes = analysisService.getAllAnalysisTypes();
    ArrayList<Sample> samples = limsService.getLatestLIMSData();

Cet appel à limsService.getLatestLIMSData() a causé l'exception suivante:

     [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.

Avoir consulté cette page, http://msdn.microsoft.com/en-us/library/ms378484.aspx (parmi beaucoup d'autres), j'ai tenté de changer la définition de la connexion piscines:

Connection Pool:
Name: BEACHWATER_LIMS
Datasource Classname: com.microsoft.sqlserver.jdbc.SQLServerXADataSource
Resource Type: javax.sql.XADataSource

Ping via la console d'administration de Glassfish réussit, mais appel à analysisService.getAllAnalysisTypes() lève une exception:

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'."

Des idées?

OriginalL'auteur Sorcha | 2010-04-09