“Transaction locale a déjà 1 non-XA Ressource: impossible d'ajouter plus de ressources” erreur
Après la lecture des questions précédentes sur cette erreur, il semble que tous d'entre eux conclure que vous avez besoin pour activer XA sur toutes les sources de données. Mais:
- Que faire si je ne veux pas distribué
transaction? Que ferais-je si je veux
début des opérations sur deux
bases de données en même temps, mais
valider la transaction sur une base de données
et de revenir sur la transaction sur
de l'autre? - Je me demande comment mon code
lancé effectivement distribué
des transactions. Il ressemble pour moi comme je suis
départ complètement séparé
les transactions sur chacun des
les bases de données.
Info à propos de l'application:
L'application est un EJB en cours d'exécution sur une Java de Sun Application Server 9.1
- Je utiliser quelque chose comme le printemps suivant contexte, d'établir la session hibernate usines:
<bean id="dbADatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dbA"/>
</bean>
<bean id="dbASessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dbADatasource" />
<property name="hibernateProperties">
hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
hibernate.default_schema=schemaA
</property>
<property name="mappingResources">
[mapping resources...]
</property>
</bean>
<bean id="dbBDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dbB"/>
</bean>
<bean id="dbBSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dbBDatasource" />
<property name="hibernateProperties">
hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
hibernate.default_schema=schemaB
</property>
<property name="mappingResources">
[mapping resources...]
</property>
</bean>
À la fois de la JNDI ressources sont javax.sql.ConnectionPoolDatasoure. En fait ils pointent vers le même pool de connexion, mais nous avons deux différentes ressources JNDI parce qu'il y a la possibilité que les deux, complètement séparées, des groupes de tables se déplacer à différentes bases de données dans le futur.
Ensuite dans le code, je n':
sessionA = dbASessionFactory.openSession();
sessionB = dbBSessionFactory.openSession();
sessionA.beginTransaction();
sessionB.beginTransaction();
La sessionB.beginTransaction() de la ligne de produit l'erreur dans le titre de ce post - parfois. J'ai couru à l'application sur deux différents soleil serveurs d'applications. Sur l'un fonctionne bien, l'autre génère l'erreur. Je ne vois pas de différence dans la façon dont les deux serveurs sont configurés bien qu'ils ne se connectent pas aux différent, mais équivalent des bases de données.
La question est donc
- Pourquoi ne pas le code ci-dessus démarrer
totalement indépendant des transactions? - Comment puis-je le forcer à démarrer
transactions indépendantes plutôt que de
une transaction distribuée? - Quelle configuration pourrait causer la différence dans
comportement entre les deux applications
les serveurs?
Grâce.
P. S. la trace de la pile est:
Local transaction already has 1 non-XA Resource: cannot add more resources.
at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.enlistResource(J2EETransactionManagerOpt.java:124)
at com.sun.enterprise.resource.ResourceManagerImpl.registerResource(ResourceManagerImpl.java:144)
at com.sun.enterprise.resource.ResourceManagerImpl.enlistResource(ResourceManagerImpl.java:102)
at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:216)
at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:327)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:189)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:158)
at com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:108)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at [application code ...]
OriginalL'auteur jthg | 2010-05-20
Vous devez vous connecter pour publier un commentaire.
L'application. le serveur gère la transaction pour vous qui peuvent, si nécessaire, être une transaction distribuée. Il fait appel à tous les participants automatiquement. Quand il n'y a qu'un seul participant, vous ne remarquez pas de différence avec un simple JDBC de la transaction, mais si il y a plus d'une, d'une transaction distribuée est vraiment nécessaire, par conséquent l'erreur.
Vous pouvez configurer la source de données à être XA ou Local. Le comportement transactionnel de Spring/Hibernate peut également être configuré pour utiliser soit des transactions JDBC ou déléguer la gestion de transactions JTA distributed transaction manager.
Je vous suggère de l'interrupteur de la source de données pour les non-XA et essayez de configurer Spring/Hibernate pour l'utilisation de JDBC transactions. Vous devriez trouver les informations pertinentes dans le la documentation, voici ce que je soupçonne est la ligne à modifier:
Ce qui devrait essentiellement signifie que vous n'êtes pas à l'aide de l'application. server distributed transaction manager.
Si vous avez vraiment exactement la même application et la configuration, cela signifie que, dans un cas, un seul participant est enrôlé dans la dist. de la transaction, alors qu'il ya deux dans le 2ème cas. Un participant correspond à une connexion à une base de données d'habitude. Se pourrait-il que dans un cas, vous devez utiliser deux de schéma sur deux bases de données différentes, alors que dans le 2ème cas, vous utilisez deux schéma sur le même physique de la base de données? Plus probable explication serait que la source de données ont été configurés différemment sur les deux app. serveur.
PS: Si vous utilisez JTA des transactions distribuées, vous devez utiliser
UserTransaction.{begin,commit,rollback}
plutôt que leur équivalent sur leSession
.session.beginTransaction
dans un environnement géré, mais il semble que Hibernate va rejoindre automatiquement le courant de transaction JTA dans un environnement JTA si vous le faites (pour les CMT et même BMT, Hibernate va commencer uneUserTransation
si nécessaire). Voir redhat.com/docs/en-US/JBoss_Hibernate/3.2.4.sp01.cp03/html/...OriginalL'auteur ewernli
Non, pas tous, tous sauf un (comme l'exception, c'est dire) si votre serveur d'application prend en charge la Journalisation Dernière Ressource (LLR) optimisation (qui permet d'enrôler un non-XA ressource dans une transaction globale).
Parce que vous ne l'êtes pas. Lors de l'utilisation de
beginTransaction()
derrière EJB ejb Session Hibernate va rejoindre la transaction JTA (reportez-vous à la la documentation pour plus de détails). Ainsi, le premier appel, tout fonctionne, mais l'appel de la deuxième moyen à l'enrôlement d'un autre ressources de transaction de la transaction en cours. Et puisque aucune de vos ressources XA, vous obtenez une exception.Voir @ewernli réponse.
Aucune idée. Peut-être que l'un d'eux est d'utiliser au moins un XA source de données.
"Non, pas tous, tous sauf un" - c'est vrai, merci pour cette remarque
FWIW, LLR (aka LPS / dernier participant de soutien en A) présente le risque d'une heuristique de danger: si la 1PC ressources ne répond pas (délai d'attente, la perte de connexion, etc.), il n'y a aucun moyen de savoir ce que le résultat de la XA ressources des branches.
Merci pour ce partage.
OriginalL'auteur Pascal Thivent