Spring - Est-il possible d'utiliser les gestionnaires de transactions multiples dans la même application?
-
09-10-2019 - |
Question
Je suis nouveau au printemps et je me demande s'il est possible d'utiliser de nombreux gestionnaires de transactions dans la même application?
J'ai deux couches d'accès aux données - un pour les deux bases de données. Je me demande, comment allez-vous sur l'utilisation de l'un des gestionnaires de transactions pour une couche et autre gestionnaire de transactions pour l'autre couche. Je ne ai pas besoin d'effectuer des transactions sur les deux bases de données - encore. Mais je besoin d'effectuer des transactions sur chaque base de données. J'ai créé une image pour aider les grandes lignes de mon problème:
Voici ma configuration de contexte d'application:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:component-scan base-package="cheetah.repositories" />
<tx:annotation-driven />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="accounts" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
Voici un exemple qui utilise cette configuration:
@Repository
public class JpaAccountRepository implements AccountRepository {
@PersistenceContext(unitName = "cheetahAccounts")
private EntityManager accountManager;
@Override
@Transactional
public Account findById(long id) {
Account account = accountManager.find(Account.class, id);
return account;
}
}
Donc, pour le dépôt de compte, je veux utiliser une usine de gestionnaire d'entités avec l'unité de persistance ensemble aux comptes. Cependant, avec mon BusinessData Repository, je veux utiliser une usine de gestionnaire d'entités avec une unité de persistance différente. Comme je ne peux définir un grain de gestionnaire de transactions, comment puis-je sur l'utilisation de différents gestionnaires de transactions pour les différents référentiels?
Merci pour toute aide.
La solution
Si vous utilisez une annotation @Transactional
, vous pouvez spécifier le gestionnaire de transactions à utiliser en ajoutant un ensemble d'attributs à un nom ou un qualificatif haricot. Par exemple, si votre contexte d'application définit plusieurs gestionnaires de transactions avec des qualificatifs:
<bean id="transactionManager1"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory1" />
<qualifier value="account"/>
</bean>
<bean id="transactionManager2"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
<qualifier value="businessData"/>
</bean>
Vous pouvez utiliser le qualificatif pour spécifier le gestionnaire de transactions à utiliser:
public class TransactionalService {
@Transactional("account")
public void setSomethingInAccount() { ... }
@Transactional("businessData")
public void doSomethingInBusinessData() { ... }
}
Autres conseils
Cette entrée Spring Jira aborde la question un peu:
https://jira.spring.io/browse/SPR-3955
Je pense que ce pourrait être un gestionnaire de transactions par connexion si vous ne l'utilisez validation en deux phases. Vous avez juste besoin de créer deux gestionnaires de transactions et injectent eux avec la connexion appropriée.
Mais je dois poser la question: pourquoi pensez-vous que vous avez besoin de deux gestionnaires de transactions? Vous pouvez avoir plus d'une connexion de base de données. Les OTI qui utilisent les connexions peuvent et doivent être instanciés par différents services, dont chacun peut être annotés avec leurs propres paramètres transactionnels. Un gestionnaire peut accueillir à la fois. Pourquoi pensez-vous que vous avez besoin de deux?