具有两个数据源的 Spring Boot Batch 导致 javax.persistence.TransactionRequiredException:执行更新/删除查询
Posted
技术标签:
【中文标题】具有两个数据源的 Spring Boot Batch 导致 javax.persistence.TransactionRequiredException:执行更新/删除查询【英文标题】:Spring Boot Batch with two Datasources causes javax.persistence.TransactionRequiredException: Executing an update/delete query 【发布时间】:2021-02-12 02:16:45 【问题描述】:我有一个spring boot batch
项目,其中包含两个数据源,一个用于批处理表,一个用于业务表。它可以很好地从业务数据库中读取。
我的配置看起来像
@Configuration
@EnableBatchProcessing
public class DataSourceConfiguration
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource()
return DataSourceBuilder.create().build();
@Bean
@ConfigurationProperties(prefix = "spring.sybasedatasource")
public DataSource sybaseDataSource()
return DataSourceBuilder.create().build();
@Bean
BatchConfigurer batchConfigurer(DataSource dataSource)
return new DefaultBatchConfigurer(dataSource);
@Bean
TaskConfigurer taskConfigurer(DataSource dataSource)
return new DefaultTaskConfigurer(dataSource);
但是当我执行更新时
public interface DocumentRepository extends JpaRepository<DocumentDescriptor, Integer>
@Modifying
@Query(value = "update document set process_status = :status where process_status = 10001 and document_id = :documentId")
int updateDocumentStatus(Integer status, Integer documentId);
我得到一个
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
我已经查看了一些 *** 问题并将@Transactional
添加到存储库方法中。另外我创建了专用的TransactionManager
@Bean(name="tm1")
public PlatformTransactionManager tm1(@Qualifier ("dataSource") DataSource datasource)
return new DataSourceTransactionManager(datasource);
@Bean(name="tm2")
public PlatformTransactionManager tm2(@Qualifier ("sybaseDataSource") DataSource datasource)
return new DataSourceTransactionManager(datasource);
并使用@Transaction("tm2")
,但异常仍然相同。
任何想法如何获得正确的交易?
【问题讨论】:
你是如何为 crud repos 设置实体管理器的?以某种方式检查事务是否未被某些库禁用。 我没有设置任何实体管理器,也没有扫描 repo 类。我用spring-boot-starter-data-jpa
你应该设置 entityManager 并扫描,这样做后看看它是否有效。
谢谢@sonus21。它把我推向了正确的方向。我用解决方案更新了我的帖子。
您应该在解决方案中添加答案,而不是将其添加到问题描述中。
【参考方案1】:
我解决了
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages =
"...",
entityManagerFactoryRef = "sybaseEntityManagerFactory",
transactionManagerRef = "sybaseTransactionManager"
)
public class DataSourceConfiguration
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource()
return DataSourceBuilder.create().build();
@Bean
@ConfigurationProperties(prefix = "spring.sybasedatasource")
public DataSource sybaseDataSource()
return DataSourceBuilder.create().build();
@Bean
public LocalContainerEntityManagerFactoryBean sybaseEntityManagerFactory()
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), Collections.emptyMap(), null)
.dataSource(sybaseDataSource())
.packages("...")
.persistenceUnit(DataSourceConfiguration.class.getSimpleName())
.build();
@Bean
@Primary
public DataSourceTransactionManager postgresTransactionManager(@Qualifier("dataSource") DataSource datasource)
return new DataSourceTransactionManager(datasource);
@Bean
public JpaTransactionManager sybaseTransactionManager(EntityManagerFactory entityManagerFactory)
return new JpaTransactionManager(entityManagerFactory);
和@Transactional("sybaseTransactionManager")
【讨论】:
以上是关于具有两个数据源的 Spring Boot Batch 导致 javax.persistence.TransactionRequiredException:执行更新/删除查询的主要内容,如果未能解决你的问题,请参考以下文章
在两个不同端口上具有两个服务的 Spring Boot 应用程序
具有两个身份验证的Spring boot应用。 AuthenticationManager bean问题
使用 Spring Boot 自动装配具有 jpa 和非 jpa 特征的多个数据源