Ich habe eine Anwendung, die eine Verbindung zu mehreren Datenbanken herstellen muss. Dies ist eine administrative Anwendung, die im Grunde verwendet wird, um Einträge in verschiedenen Datenbanken zu verwalten - wir müssen nicht auf mehrere Datenbanken gleichzeitig zugreifen, noch benötigen wir irgendeine Art von verteilter Transaktionsverwaltung.Richtige Methode zum Einrichten von Transaktionen im Frühling für verschiedene Datenquellen?
Grundsätzlich ein Bereich der Anwendung können Sie Geräte in der Datenbank A zu erstellen, und ein weiterer Bereich der Anwendung können Sie ähnliche Geräte in der Datenbank B. konfigurieren
Wir haben bereits Transaktionen einzurichten und perfekt funktioniert, wenn nur einer mit Datenquelle. Die Konfiguration sieht so aus:
<aop:config>
<aop:pointcut id="companyServicePoint"
expression="execution(* com.company.service.CompanyService.*(..))" />
<aop:advisor advice-ref="companyServiceTxAdvice"
pointcut-ref="companyServicePoint"/>
</aop:config>
<tx:advice id="companyServiceTxAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- set propogation required on create methods, all others are read-only -->
<tx:method name="create*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
Dies setzt einen pointcut auf jeder Ausführung von Methoden innerhalb CompanyService
und Transaktionsberatung mit dem pointcut assoziiert, die Transaktionen für alle Methoden, deren Name mit „create“ erfordert. Der Transaktionshinweis ist einem TransactionManager zugeordnet, der an die dataSource gebunden ist.
Wenn ich eine zweite (oder mehrere) Datenquellen hinzufüge, wie kann ich den gleichen Transaktionshinweis auf andere Datenquellen anwenden? Da der AOP-Hinweis nur einem transactionManager zugeordnet werden kann, der nur einer dataSource zugeordnet werden kann, muss ich einen doppelten Transaktionshinweis einrichten?
Wenn ich Setup doppelte Transaktionsberatung zum gleichen pointcut, bedeutet dies nicht, dass alle Aufrufe von Methoden in meiner CompanyService
Schnittstelle propogation gegen all meine datasources benötigen?
Um meine letzte Frage ein wenig klarer zu machen, werde ich mehrere Beans deklariert haben, die die CompanyService
Schnittstelle implementieren, und jede dieser Beans wird eine separate CompanyDAO
haben, um auf ihre individuelle DataSource zuzugreifen. Ich befürchte, dass dieser Ansatz dazu führt, dass beim Aufruf der Bean companyService1
der Transaktionshinweis unter all
firmaService-Beans/dataSources ausgelöst wird.
Gehe ich in die falsche Richtung?
Update: Ich habe tatsächlich die Konfiguration, die ich oben gesprochen testeten (Anbringen von zwei Berater der gleichen pointcut) und Aufrufen einer beliebigen Methode auf entweder einzelne Instanz der CompanyService
Umsetzung ist in der Tat auf beiden neuen Transaktionen erstellen Datasources wie erwartet:
DEBUG company.serviceDataSourceTransactionManager - Creating new transaction with name [com.company.service.CompanyService.createCompany]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG company.serviceDataSourceTransactionManager - Acquired Connection [connection1 string here...] for JDBC transaction
...
DEBUG company.serviceDataSourceTransactionManager - Creating new transaction with name [com.company.service.CompanyService.createCompany]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG company.serviceDataSourceTransactionManager - Acquired Connection [connection2 string here...] for JDBC transaction
...
DEBUG company.serviceDataSourceTransactionManager - Rolling back JDBC transaction on Connection [connection1 string here...]
...
DEBUG company.serviceDataSourceTransactionManager - Rolling back JDBC transaction on Connection [connection2 string here...]
Dies scheint es Probleme auf dem Weg führen würde, da entweder CompanyService
Instanz immer nur mit einem einzigen Datasource arbeitet.
Gibt es einen besseren Weg zu konfigurieren, was ich erreichen möchte?
Danke, das funktioniert gut - nur eine einzige Transaktion wird erstellt, wenn eine Bean-Instanz aufgerufen wird. Nicht so elegant wie der Pointcut auf der Schnittstelle zu deklarieren, aber das ist es, was mein Anwendungsfall erfordert ... –