Spring - Как правильно настроить @Transactional с двумя источниками данных? - PullRequest
0 голосов
/ 07 июня 2019

У меня есть две весенние конфигурации источника данных, которые выглядят так:

@EnableJpaRepositories(basePackages = {"XXXXXX",
                                       "XXXXXX"}, entityManagerFactoryRef = "postgreSqlEM", transactionManagerRef = "postgreSqlTM")
@EnableTransactionManagement
@Configuration
public class PostgreSqlDataSourceConfig {

    @Primary
    @Bean
    @ConfigurationProperties("spring.postgresql.hikari")
    public HikariConfig postgreSqlHikariConfig() {
        return new HikariConfig();
    }

    @Primary
    @Bean
    public DataSource postgreSqlDataSource() {
        return new HikariDataSource(postgreSqlHikariConfig());
    }

    @Primary
    @Bean("postgreSqlEM")
    public LocalContainerEntityManagerFactoryBean postgreSqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(postgreSqlDataSource()).packages("XXXXXX",
                                                                   "XXXXXX",
                                                                   "XXXXXX")

                      .build();
    }

    @Primary
    @Bean("postgreSqlTM")
    public JpaTransactionManager postgreSqlTransactionManager(@Qualifier("postgreSqlEM") EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Primary
    @Bean
    public EntityManager getEntityManager(@Qualifier("postgreSqlEM") EntityManagerFactory emf) {
        return emf.createEntityManager();
    }
}

Это @Primary, поэтому на него должны указывать все @Transactional без конфигурации значений, а также все инъекции EntityManager.

Spring-загрузка запускается правильно, но все аннотации @Transactional игнорируются.

Я получаю сообщения об ошибках, подобных этому:

javax.persistence.TransactionRequiredException: javax.persistence.Query.executeUpdate requires active transaction

Как правильно настроить его, чтобы @Transactionalработает?

Я на весенней загрузке 2.1.5. RELEASE.

Ответы [ 2 ]

2 голосов
/ 07 июня 2019

Сначала настройте один TransactionManager на источник данных.Два источника данных означают, что у вас будет два TransactionManager.

Вот пример:

    @Bean(name = "blamTransactionManager")
    @Primary
    public PlatformTransactionManager blamTransactionManager(
        @Qualifier("blamDataSourcePool") final DataSource blamDataSource)
    {
        return new DataSourceTransactionManager(
            blamDataSource);
    }

Во-вторых, настройте ChainedTransactionManager с помощью двух диспетчеров транзакций, созданных выше.

Вот пример:

    @Bean(name = "chainedTransactionManager")
    public ChainedTransactionManager transactionManager(
        @Qualifier("blamTransactionManager") final PlatformTransactionManager blamTransactionManager,
        @Qualifier("kapowTransactionManager") final PlatformTransactionManager kapowTransactionManager)
    {
        return new ChainedTransactionManager(
            blamTransactionManager,
            kapowTransactionManager);
    }

Наконец, укажите ссылку на chainedTransactionManager в аннотации транзакции.

Например:

    @Transactional("chainedTransactionManager")
0 голосов
/ 07 июня 2019

Я сделал нечто подобное, поместив сущности, которые работают с одной транзакцией, в отдельный пакет.Вот как я настроил один источник данных (у меня есть четыре разных источника данных).

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "firstEntityManagerFactory",
    basePackages = "com.example.repository.first"
)
public class FirstDbConfig {

    @Bean(name = "firstDataSource")
    @ConfigurationProperties(prefix = "first.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "firstEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("firstDataSource") DataSource dataSource
    ) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.domain.first")
                .persistenceUnit("first")
                .build();
    }

    @Bean(name = "firstTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("firstEntityManagerFactory") EntityManagerFactory
                    entityManagerFactory
    ) {
        return new JpaTransactionManager(entityManagerFactory);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...