Question

J'ai un fichier applicationContext.xml et deux org.springframework.orm.jpa.JpaTransactionManager (chacun avec sa propre unité de persistance, différentes bases de données) configurés dans une application personnalisée Spring Middleware.

Je souhaite utiliser des transactions basées sur des annotations (@Transactional) pour ne pas déranger avec la validation, la sauvegarde et la restauration de TransactionStatus.

Un collègue de travail a mentionné que cette opération rendait confus cela lorsqu'il y avait plusieurs gestionnaires de transactions, même si le fichier de contexte est configuré correctement (les références vont à l'unité de persistance correcte). Quelqu'un a déjà vu un problème?

Dans votre configuration, auriez-vous deux gestionnaires de transactions? Auriez-vous txManager1 et txManager2?

C’est ce que j’ai avec JPA, deux beans Spring différents qui sont des gestionnaires de transactions.

Était-ce utile?

La solution

Je suppose que vous avez 2 choix

Si vos cas d'utilisation ne nécessitent jamais de mises à jour des deux bases de données dans la même transaction, vous pouvez utiliser deux JpaTransactionManagers, mais je ne suis pas sûr que vous pourrez utiliser l'approche @Transactional? Dans ce cas, vous devrez utiliser l'ancien mécanisme consistant à utiliser un simple TransactionProxyFactoryBean pour définir les limites des transactions, par exemple:

<bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
<bean id="firstService"  
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="firstJpaTm"/>
    <property name="target" ref="firstRealService"/>
    <property name="transactionAttributes">
        <props>
           <prop key="insert*">PROPAGATION_REQUIRED</prop>
           <prop key="update*">PROPAGATION_REQUIRED</prop>
           <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>
<!-- similar for your second service -->

Si vous avez besoin d'une transaction couvrant les deux bases de données, vous devrez utiliser un gestionnaire de transactions JTA. Les API :

  

Ce gestionnaire de transactions convient aux applications utilisant un seul JPA EntityManagerFactory pour l’accès aux données transactionnelles. JTA (généralement via JtaTransactionManager) est nécessaire pour accéder à plusieurs ressources transactionnelles au sein d'une même transaction. Notez que vous devez configurer votre fournisseur JPA en conséquence afin de le faire participer aux transactions JTA.

Cela signifie que vous devrez fournir un gestionnaire de transactions JTA. Dans notre application, nous utilisons une configuration semblable à celle-ci:

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManagerName" value="appserver/jndi/path" />
</bean>

Si vous déployez au sein d’un serveur d’applications, JtaTransactionManager de printemps doit rechercher le véritable gestionnaire de transactions JTA compatible XA fourni par le serveur d’applications. Cependant, vous pouvez également utiliser un gestionnaire de transactions JTA autonome (mais je ne l'ai pas encore essayé moi-même).

En ce qui concerne la configuration du fournisseur de persistance Jpa, je ne le connais pas bien. Quel fournisseur de persistance JPA utilisez-vous?

Le code ci-dessus est basé sur notre approche, dans laquelle nous utilisions la version native d'Hibernate, par opposition à la mise en œuvre de l'application JPA d'Hibernate. Dans ce cas, nous avons réussi à supprimer les deux beans HibernateTransactionManager et à nous assurer simplement que les deux SessionFactories ont été injectés avec le même JTA TM, puis à utiliser l'élément tx: annotation-driven.

J'espère que cela vous aidera

Autres conseils

La seule situation dans laquelle vous pouvez avoir deux gestionnaires de transactions Spring est si vous ne les ouvrez jamais en même temps. Cela n’est pas intrinsèquement lié aux transactions distribuées - les mêmes restrictions s’appliquent même si vous souhaitez que les deux sources de données aient des styles de vie de transaction complètement séparés (mais se chevauchant potentiellement dans le temps).

En interne, les gestionnaires de transactions de Spring utilisent tous le logiciel TransactionSynchronizationManager de Spring, qui conserve un tas d’états critiques dans des variables statiques ThreadLocal. Les gestionnaires de transactions ont ainsi la garantie de basculer les uns sur les autres.

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