【发布时间】:2020-08-06 01:20:11
【问题描述】:
在我的 Spring Batch 作业的其中一个步骤中,我正在尝试对其进行配置,以便当 ObjectOptimisticLockingFailureException 发生时,可以重试该步骤,并希望重试能够奏效。
@Bean
public Step myStep(StaxEventItemReader<Response> staxEventResponseReader,
ItemWriter<Response> itemWriter,
ItemProcessor<? super Response, ? extends Response> responseProcessor) {
return stepBuilderFactory.get("myStep")
.<Response, Response>chunk(1)
.reader(staxEventResponseReader)
.processor(responseProcessor)
.writer(itemWriter)
//.faultTolerant().retryLimit(3).retry(Exception.class)
.build();
}
该步骤的 writer 逻辑非常简单:它尝试从数据库中读取一行,一旦找到该行,它就会更新它。我能够通过在 find 方法之后设置断点来重现ObjectOptimisticLockingFailureException,手动碰撞数据库中行的version 列并提交它,然后继续。
但是,在我的步骤中取消注释重试定义后,没有尝试重试。经过一些调试,似乎 Spring 重试逻辑在块的事务中;但由于 ObjectOptimisticLockingFailureException 不是由我在编写器中的代码抛出的,而是由 Spring 的块事务提交逻辑抛出的,因此根本没有尝试重试。
Chunk Transaction Begin
Begin Retry loop in FaultTolerantChunkProcessor.write()
Writer logic in my Step
End Retry loop
Chunk Transaction Commit - Throws ObjectOptimisticLockingFailureException
当我尝试在我的 writer 中显式抛出 ObjectOptimisticLockingFailureException 时,重试逻辑按预期完美运行。我的问题是:
- 如果在步骤中我的编写器代码没有抛出异常,但在 Spring Batch 提交块事务时,如何使重试逻辑工作?
- 另一个奇怪的行为是,当我通过碰撞数据库中的版本列手动导致
ObjectOptimisticLockingFailureException时,在步骤中注释了重试定义,步骤的最终状态是预期的失败。但是在未注释重试定义的情况下,该步骤的最终状态是 COMPLETE。这是为什么呢?
【问题讨论】:
标签: java spring-boot spring-batch spring-retry