2010-12-12 12 views
54

Ich bin neu in Spring und ich frage mich, ob es möglich ist, zahlreiche Transaktionsmanager in der gleichen Anwendung zu verwenden?Spring - Können mehrere Transaktionsmanager in derselben Anwendung verwendet werden?

Ich habe zwei Datenzugriffsschichten - eine für beide Datenbanken. Ich frage mich, wie Sie einen Transaktionsmanager für eine Schicht und einen anderen Transaktionsmanager für die andere Schicht verwenden. Ich muss Transaktionen in beiden Datenbanken noch nicht durchführen. Aber ich muss Transaktionen für jede Datenbank einzeln durchführen. Ich habe ein Bild erstellt, um mein Problem zu umreißen:

alt text

Hier ist meine Anwendungskontext Konfiguration:

<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> 

Hier ist ein Beispiel, dass diese Konfiguration verwendet:

@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; 
    } 
} 

Also für das Konto-Repository, ich möchte eine Entity Manager Factory mit der Persistenz-Einheit für Konten verwenden. Mit meinem BusinessData Repository möchte ich jedoch eine Entity Manager Factory mit einer anderen Persistenzeinheit verwenden. Da ich nur einen Transaktionsmanager-Bean definieren kann, wie kann ich verschiedene Transaktionsmanager für die verschiedenen Repositories verwenden?

Danke für jede Hilfe.

Antwort

75

Wenn Sie eine @Transactional Annotation verwenden, können Sie hinzufügen, indem Sie einem Bean-Namen oder Qualifier ein Attribut hinzufügen. Zum Beispiel legt fest, ob Ihr Anwendungskontext mehr Transaktionsmanager mit Qualifier:

<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> 

Sie die Qualifikation können Sie den Transaktions-Manager angeben, verwenden:

public class TransactionalService { 

    @Transactional("account") 
    public void setSomethingInAccount() { ... } 

    @Transactional("businessData") 
    public void doSomethingInBusinessData() { ... } 
} 
+0

Was ist, wenn es eine Methode gibt, die Daten aus der Datenbank liest, wo Sie nicht die @ Transactional Annotation für Datenbanklesevorgänge verwenden müssen. – ziggy

+0

Danke für Ihre Antwort! aber du hast dieses '' verloren – Dozer

5

dieses Frühjahr Jira Eintrag diskutiert das Problem ein wenig:

https://jira.spring.io/browse/SPR-3955

Ich denke, es ist ein Transaktions-Manager pro Verbindung sein könnte, wenn Sie nicht zweiphasige Festschreibung verwenden. Sie müssen nur zwei Transaktionsmanager erstellen und diese mit der entsprechenden Verbindung einbinden.

Aber ich muss die Frage stellen: Warum brauchen Sie zwei Transaktionsmanager? Sie können mehr als eine Datenbankverbindung haben. Die DAOs, die die Verbindungen verwenden, können und sollten von verschiedenen Diensten instanziiert werden, von denen jede mit ihren eigenen Transaktionseinstellungen versehen werden kann. Ein Manager kann beides unterbringen. Warum denkst du, du brauchst zwei?

+9

Ich dachte, ich brauchte zwei Transaktionsmanager, weil die Transaktion Manager gibt die Entity Manager-Factory an, die wiederum die zu verwendende Persistenzeinheit angibt. –