Comment configurer la gestion des transactions pour travailler avec 2 différents db au printemps?
-
21-09-2019 - |
Question
J'ai 2 bases de données (MySql et HSQLDB). J'ai configuré 2 sources de données et 2 haricots EntityManagerFactory. Je peux aussi configurer 2 correspondant haricots JpaTransactionManager.
Mais je ne sais pas comment spécifier lequel doit être utilisé pour gérer les transactions de service de classe concrète. Je veux utiliser l'annotation @Transactional
à cette fin, mais je peux effectivement préciser que l'un des txManagers:
<tx:annotation-driven transaction-manager="manager"/>
Qu'est-ce que la sortie de cette situation?
La solution
Le javadoc JpaTransactionManager a quelques conseils à ce sujet:
Ce gestionnaire de transactions est approprié pour les applications qui utilisent une seule Assemblée parlementaire paritaire EntityManagerFactory pour l'accès aux données transactionnelles. JTA (Généralement par JtaTransactionManager) est nécessaire pour l'accès multiple transactionnel ressources dans la même transaction. Notez que vous devez configurer votre fournisseur JPA en conséquence afin de faire participer à JTA transactions.
En d'autres termes, si vous vous retrouvez avec plusieurs gestionnaires d'entités, avec les gestionnaires correspondant tx, alors vous devriez envisager d'utiliser un seul JtaTransactionManager
à la place. Les gestionnaires d'entités devraient pouvoir participer à des transactions JTA, et cela vous donnera transactionnalité complète à travers les deux gestionnaires d'entités, sans hacving à vous soucier de gestionnaire entité que vous êtes à un moment donné.
Bien sûr, JtaTransactionManager
nécessite un serveur d'application complète de support JTA, plutôt qu'un moteur de servlet Tomcat comme la vanille.
Autres conseils
Déclarez votre <tx:annotation-driven>
sans transaction-manager attribut, qualifiés pour déclarer les gestionnaires de transactions comme celle-ci:
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="txManager1"/>
</bean>
Utilisez ce qualificatif dans @Transactional valeur pour sélectionner l'un des gestionnaires de transaction:
@Transactional("txManager1")
ou avec d'autres propriétés:
@Transactional(value = "txManager1", readOnly = true)
Depuis son après une longue date puisque les réponses correctes.
Skaffman peut être correcte en termes de facilité d'utilisation JpaTransactionManager pour plusieurs bases de données.
Mais il y a une solution de travail pour l'utilisation de 2 bases de données différentes avec 2 différents JpaTransactionManager.
@Bean(name = "db2TransactionManager")
public PlatformTransactionManager transactionManager2() throws NamingException {
JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
return txManager;
}
@Bean
@Primary
public PlatformTransactionManager transactionManager() throws Exception {
JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
txManager.setNestedTransactionAllowed(true);
return txManager;
}
@Primary
doit être utilisé pour spécifier pour ceux où vous ne spécifiez pas le nom qualificatif dans @Transactional
Vous devez spécifier deux gestionnaires de transactions pour ce en context.xml d'application comme suit:
<tx:annotation-driven transaction-manager="manager1"/>
<tx:annotation-driven transaction-manager="manager2"/>
attribut @Transactional va maintenant utiliser son gestionnaire de transactions pertinentes.