EJB3 - en utilisant 2 unités de persistance dans une transaction (Exception: transaction locale a déjà 1 des ressources non-XA)

StackOverflow https://stackoverflow.com/questions/2606497

Question

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

Les 2 unités de persistance sont définies 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 aux ressources JDBC et les pools de connexions que j'avais définis dans Glassfish comme suit (inclure un ici car les deux sont identiques à part les noms et les informations de connexion de base de données):

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 grains de session sans état, LimsServiceBean, AnalysisServiceBean et AnalysisDataTransformationServiceBean.

Voici les extraits pertinents 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 provoqué 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.

Après avoir consulté cette page, http://msdn.microsoft.com/ fr-fr / bibliothèque / ms378484.aspx (parmi beaucoup d'autres), j'ai essayé de changer la définition des pools de connexion à:

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

Ping via la console d'administration Glassfish réussit, mais appeler à analysisService.getAllAnalysisTypes () lance maintenant 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'."

Toutes les idées?

Était-ce utile?

La solution

Modifier la configuration de pool de connexion dans Glassfish:

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

Suivez les étapes sur le blog de Senthil Balakrishnan, "Comment faire MSSQL serveur XA Datasource travail?" ici, http: // www .senthilb.com / 2010/01 / how-to-make-xa-datasource-work-in-mssql.html .

Redémarrer Glassfish.

Autres conseils

Pour utiliser deux unités de persistance (et donc deux sources de données) dans une transaction, vous avez besoin en effet d'utiliser des connexions XA et pour configurer vos pools en conséquence (au moins un d'entre eux, GlassFish prend en charge la dernière optimisation de l'agent qui permet de faire appel une ressource non XA, consultez http: //docs.sun .com / app / docs / doc / 820-7695 / beanm? a = vue ). Ce fut pour la première erreur.

Pour la deuxième erreur, il semble difficile de dire quoi que ce soit avec le niveau actuel des détails. Pourriez-vous donner la trace de la pile (activer la journalisation plus fine si nécessaire)?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top