Как запустить два независимых менеджера транзакций для источников данных jpa и jdbc

#java #spring #spring-boot #jpa #jdbc

#java #spring #весенняя загрузка #jpa #jdbc

Вопрос:

Я разрабатываю отдельное приложение со следующим стеком технологий:

  • Весенняя загрузка версии 2.1.0.RELEASE
  • Система Oracle12c с драйвером ojdbc6 (11.2.0.3)
  • Apache Camel
  • JPA для основного источника данных
  • JDBC для вторичного источника данных (только для чтения)

Источник данных JPA является основным источником данных, к которому подключается само приложение и в который записываются данные. JDBC — это дополнительный источник данных для чтения данных из базы данных с другой целью.

Во время выполнения я сталкиваюсь со следующей проблемой:

Я опрашиваю / выбираю объект JPA из основного источника данных и выполняю некоторую обработку. Эта обработка включает в себя выполнение запроса select для вторичного источника данных через шаблон jdbc. Теперь, если выполнение запроса выдает исключение, я могу его перехватить и хочу обновить поле состояния объекта JPA и записать его в источник данных.

Я уже читал, что Oracle пытается выполнить откат, если возникает исключение SQLException. Проблема в том, что мой источник данных JPA не может зафиксировать изменения в объекте, которые я делаю, когда запрос JDBC завершается с ошибкой.

Мне кажется, что два источника данных / менеджера транзакций не полностью независимы друг от друга и что исключение во вторичном источнике данных вызывает ошибки в первичном источнике данных во время фиксации изменений.

Возможно ли это вообще? Если да, то как я могу настроить два независимых менеджера транзакций?

РЕДАКТИРОВАТЬ: я уже пытался аннотировать соответствующие методы и классы с помощью @Transactional(noRollbackFor = Exception.class ) но это не решает проблему.

Вот две конфигурации источника данных:

ApplicationDatasourceConfig (JPA)

 @Configuration
@EnableJpaRepositories(basePackages = "foo.bar.repository.jpa",
                       entityManagerFactoryRef = "applicationEntityManagerFactory",
                       transactionManagerRef = "applicationTransactionManager")
@ConfigurationProperties(prefix = "spring.datasource.hikari")
@EnableTransactionManagement
public class ApplicationDatasourceConfig extends HikariConfig{

@Bean("applicationDatasource")
@Primary
public DataSource applicationDataSource(){
    return new HikariDataSource(this);
}

@Bean("applicationDatasourceProperties")
@Primary
public DataSourceProperties dataSourceProperties(){
    return new DataSourceProperties();
}

@Bean("applicationEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean applicationEntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                              @Qualifier("applicationDatasource") DataSource dataSource){
    return builder
            .dataSource(dataSource)
            .packages("foo.bar.entity")
            .build();
}

@Bean("applicationTransactionManager")
@Primary
public PlatformTransactionManager applicationTransactionManager(@Qualifier("applicationEntityManagerFactory")EntityManagerFactory entityManagerFactory){
    return new JpaTransactionManager(entityManagerFactory);
}
}
  

SecondaryDatasourceConfig (JDBC)

 @Configuration
@ConfigurationProperties(prefix = "secondary.datasource")
@EnableTransactionManagement
public class SecondaryDatasourceConfig {

@Bean("secondaryDatasource")
public DataSource secondaryDataSource(){
    return secondaryDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
public DataSourceProperties secondaryDataSourceProperties(){
    return new DataSourceProperties();
}

@Bean("secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryDatasource") DataSource secondaryDataSource){
    return new DataSourceTransactionManager(secondaryDataSource);
}
}