Spring boot 自定义数据库连接赢得';错误时无法回滚(Spring批处理:块)
在我的第一份Spring Batch chunk工作中(我是初学者),Spring boot 自定义数据库连接赢得';错误时无法回滚(Spring批处理:块),spring-boot,spring-batch,Spring Boot,Spring Batch,在我的第一份Spring Batch chunk工作中(我是初学者), 我编写了db实用程序类,以便在区块步骤中使用, 因为我需要覆盖application.properties设置的默认连接属性。 但是,它会导致错误的回滚问题(从不回滚)。 有什么改进这些逻辑的建议吗? DBUtility类 // Construct public DBUtility() { ... some business logic to get connection attributes dynamicall
我编写了db实用程序类,以便在区块步骤中使用,
因为我需要覆盖application.properties设置的默认连接属性。
但是,它会导致错误的回滚问题(从不回滚)。
有什么改进这些逻辑的建议吗?
DBUtility类
// Construct
public DBUtility() {
... some business logic to get connection attributes dynamically.
}
@Bean
@BatchDataSource
@Primary
public DriverManagerDataSource getConnection() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverNameGottenAbove);
dataSource.setUrl(urlGottenAbove);
dataSource.setUsername(userNameGottenAbove);
dataSource.setPassword(passwordGottenAbove);
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager(){
DataSourceTransactionManager dtm = new DataSourceTransationManager(getConnection());
dtm.setRollbackOnCommitFailure(true);
return dtm;
}
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(getConnection());
}
BatchConfiguration类(块)
@springboot应用程序
@启用批处理
@交易的
公共类BatchConfiguration扩展了DefaultBatchConfigurer{
...
私有dbUtil;
专用驱动程序管理器数据源ds;
私人平台TransactionManager ptm;
//构造
公共批处理配置(){
dbUtil=new DBUtility();
ds=dbUtil.getConnection();
ptm=dbUtil.transactionManager();
}
//凌驾
@凌驾
public JobRepository createJobRepository()引发异常{
JobRepositoryFactoryBean工厂=新的JobRepositoryFactoryBean();
setDataSource(ds);
工厂事务经理(ptm);
JobRepository repo=factory.getObject();
回购回报;
}
@豆子
公共作业批处理作业(){
返回jobBuilderFactory.get(“BatchJob”)
.incrementer(新的RunIdIncrementer())
.listener(jobListener())
.flow(步骤1())
.end().build();
}
@豆子
公共步骤第1步(){
DefaultTransactionAttribute att=新的DefaultTransactionAttribute();
att.setPropagationBehavior(Propagation.REQUIRED.value());
返回stepBuilderFactory.get(“step1”)
.交易经理(ptm)
.listener(stepListener())
.chunk(提交间隔)
.reader(reader())
.processor(processore())
.writer(writer())
.readeristransacationalqueue()
.交易属性(att)
.build();
}
...
}
感谢您查看此帖子。您似乎在作业存储库(ptm)和步骤(transactionManager)上设置了两个不同的事务管理器。这是有意的吗?@MahmoudBenHassine谢谢你的评论。这是我丢失的副本,实际上我在“createJobRepository()”和“step1()”中都设置了“ptm”如上所述,不需要在
BatchConfiguration
上添加@Transactional
(这意味着此类上的方法应该在对配置代码没有意义的事务中运行)<代码>传播。必需的已经是默认值,在这种情况下为什么要创建一个defaultTransactionaAttribute
?stepBuilderFactory
将在该步骤上设置事务管理器,您无需自己执行。现在针对您的问题,您希望回滚事务的错误是什么?在读/处理/写等过程中是否出现异常?什么时候发生的?@MahmoudBenHassine我尝试了&添加了各种选项,但没有成功。。。我应该清理这些未使用的代码。至于我的问题。。。我在ItemReader中调用DBUtility
和jdbcTemplate()
,以在特定条件下更新表。我还在CustomItemWriter中调用它们以进行区块提交。读卡器、处理器和写入器中都会发生异常,每个异常都会引发RuntimeException
。当异常发生时,框架总是记录RuntimeException的回滚,启动应用程序异常的事务回滚,但数据(在reader&writer中更新)仍保留在表中。至于ItemReader,我改为使用带有传播的TransactionTemplate
,需要新定义,用于手动事务(和回滚)。然后我在catch块中添加了TransactionStatus.setRollbackOnly()
。即使这样,框架也记录了“回滚”,但从未完成。这可能不是框架问题。。
@SpringBootApplication
@EnableBatchProcessing
@Transactional
public class BatchConfiguration extends DefaultBatchConfigurer {
...
private DBUtility dbUtil;
private DriverManagerDataSource ds;
private PlatformTransactionManager ptm;
// Construct
public BatchConfiguration(){
dbUtil = new DBUtility();
ds = dbUtil.getConnection();
ptm = dbUtil.transactionManager();
}
// Override
@Override
public JobRepository createJobRepository() throws Exception {
JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(ds);
factory.setTransactionManager(ptm);
JobRepository repo = factory.getObject();
return repo;
}
@Bean
public Job BatchJob() {
return jobBuilderFactory.get("BatchJob")
.incrementer(new RunIdIncrementer())
.listener(jobListener())
.flow(step1())
.end().build();
}
@Bean
public step step1() {
DefaultTransactionAttribute att = new DefaultTransactionAttribute();
att.setPropagationBehavior(Propagation.REQUIRED.value());
return stepBuilderFactory.get("step1")
.transactionManager(ptm)
.listener(stepListener())
.<Entity, Entity>chunk(COMMIT_INTERVAL)
.reader(reader())
.processor(processore())
.writer(writer())
.readerIsTransactionalQueue()
.transactionAttribute(att)
.build();
}
...
}