У меня есть приложение, которое необходимо подключить к нескольким базам данных. Это административное приложение, которое в основном используется для управления записями в разных базах данных - нам не нужно одновременно обращаться к нескольким базам данных, и нам не нужно какое-либо управление распределенными транзакциями.
В основном одна область приложения позволяет создавать гаджеты в базе данных A, а другая область приложения позволяет настраивать аналогичные гаджеты в базе данных B.
У нас уже созданы транзакции и работают отлично, используя только один источник данных. Конфигурация выглядит так:
<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>
Это устанавливает pointcut при любом выполнении любых методов в CompanyService
и связывает рекомендации по сделкам с pointcut, которые требуют транзакций для любых методов, имя которых начинается с "create". Совет по транзакциям связан с TransactionManager, который привязан к источнику данных.
При добавлении второго (или более) источников данных, как я могу применить один и тот же совет по транзакциям к другим источникам данных? Поскольку совет АОП может быть связан только с одним транзакционным менеджером, который может быть связан только с одним источником данных, мне нужно настроить повторяющиеся рекомендации по сделке?
Если я настрою дубликат рекомендаций по транзакциям на один и тот же pointcut, не означает ли это, что любые вызовы методов в моем интерфейсе CompanyService
потребуют распространения от всех моих данных?
Чтобы сделать мой последний вопрос немного яснее, у меня будет несколько объявленных beans, которые реализуют интерфейс CompanyService
, и каждый из этих beans будет иметь отдельный CompanyDAO
для доступа к их отдельному DataSource. Я боюсь, что этот подход будет означать, что при вызове companyService1
bean совет по транзакциям будет запущен на all
companyService beans/dataSources.
Я иду об этом неправильно?
Обновление: Я действительно протестировал конфигурацию, о которой я говорил выше (прикрепление двух советников к тому же pointcut), и вызов любого метода для каждого отдельного экземпляра реализации CompanyService
выполняется в факт создает новые транзакции на обоих источниках данных, как и ожидалось:
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...]
Похоже, что это вызовет проблемы в будущем, поскольку либо экземпляр CompanyService
работает только с одним DataSource.
Есть ли лучший способ настроить то, что я пытаюсь выполнить?