Я использую аннотацию @Configuration
для конфигурации Spring вместо файла xml. Я настраиваю 2 источника данных с разными фабриками сеансов и разными менеджерами транзакций. У меня возникла проблема с аннотацией @EnableTransactionManagement
. Я читал в документации, что
@EnableTransactionManagement
более гибкий; он вернется к поиску по типу для любого bean-объектаPlatformTransactionManager
в контейнере . Таким образом, имя может быть «txManager», «transactionManager» или «tm»: это просто не имеет значения.
Это означает, что какое бы имя я ни дал методу, он всегда будет искать метод, который возвращает объект PlatformTransactionManager
, пока у меня есть 2 менеджера транзакций. Теперь проблема в том, что когда я тестирую этот класс, он выдает ошибку:
org.springframework.beans.factory.NoSuchBeanDefinitionException
: Нет уникального bean-компонента типа [org.springframework.transaction.PlatformTransactionManager
] определен: ожидался одиночный bean-компонент, но обнаружено 2
. Я даже пытался иметь 2 разных класса конфигурации, но тщетно. В конфигурации xml этого не было. Я зарегистрировал оба менеджера транзакций с двумя тегами
, и все заработало. Но здесь нельзя сделать то же самое с аннотациями.
Что мне делать, если я хочу настроить 2 источника данных с 2 разными менеджерами транзакций в аннотированном классе конфигурации Spring?
В вашем классе конфигурации используйте аннотацию @EnableTransactionManagement
.
Определите менеджера транзакций в этом классе как:
@Bean(name="txName")
public HibernateTransactionManager txName() throws IOException{
HibernateTransactionManager txName= new HibernateTransactionManager();
txName.setSessionFactory(...);
txName.setDataSource(...);
return txName;
}
В вашем классе / методе, который выполняет транзакционное задание (я), аннотируйте следующим образом:
@Transactional("txName")
или
@Transactional(value = "txName")
Таким способом вы можете связать квалифицированного менеджера транзакций с именем, где бы он вам ни понадобился. Теперь вы можете иметь столько менеджеров транзакций, сколько захотите, и использовать их соответственно, где вам нужно.
Из java doc
Для тех, кто хочет установить более прямые отношения между
@EnableTransactionManagement
и точным компонентом менеджера транзакций, который будет В этом случае интерфейс обратного вызоваTransactionManagementConfigurer
может быть реализован - обратите внимание на раздел Implements и метод@Override
, аннотированный ниже:
Ваш класс @Configuration
должен реализовать интерфейс TransactionManagementConfigurer
- реализовать annotationDrivenTransactionManager
, который возвратит ссылку на transactionManager
, который следует использовать.