#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);
}
}