@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
当我试图在编写器中显式地抛出ObjectOptimisticLockingFailureException
时,重试逻辑完全按照预期工作。我的问题是:
ObjectOptimisticLockingFailureException
时,步骤中注释了重试定义,该步骤的最终状态为FAILED,这是意料之中的。但是如果重试定义未注释,则步骤的最终状态为完成。为什么?这里有一个开放的问题:https://github.com/spring-projects/spring-batch/issues/1826。解决办法是(尝试预测并)在编写器中提交时抛出任何可能发生的异常。这是您已经尝试过的,并且在您说时已经确认了它的工作原理。当我试图在编写器中显式地抛出ObjectOptimisticLockingFailureException时,重试逻辑完全按照预期
工作。
这与前一个问题有关,但由另一个问题引起:https://github.com/spring-projects/spring-batch/issues/1189。也就是说,可以在调试会话期间使用version
字段来了解工作原理,但我不建议更改代码中的version
列。Spring Batch在其乐观锁定策略中严重依赖此列,并且不希望在用户代码中更改此列的值,否则可能会发生意外行为。
我面临一个挑战,需要从SQL Server数据库中读取“未处理”的数据,处理数据,然后有选择地更新DB2数据库中的两到六个表,然后将该数据标记为在SQL Server上的原始数据库中已处理。在任何时候,如果出现任何故障,我希望所有更新都回滚。如果我有10个未处理的项目,9个良好,但有一个失败,我仍然希望9个良好的项目完成,第10个恢复到原始状态,直到我们可以研究问题并进行更正。 总体架构是,一个输
我有两个实体,即公司和用户。一个公司可以有很多用户。因此,当我保存一个公司时,它也会在一个事务中创建一个用户。如果用户的插入由于某种原因失败了,我想公司的插入应该回滚,这是目前不发生的。 因此,如果不知何故,在请求中传递的电子邮件已经存在,那么用户实体将不会被保存,所以在这种情况下,我需要公司应该回滚。你知道我怎么才能做到这一点吗?
public void A()抛出ApplicationException{ } 这是方法B(): } 显然,如果删除方法B()中的catch块,就不会出现这种行为。现在,我想知道是否有一种方法可以回滚我的事务,即使我捕捉到方法B()中的异常。谢谢!!!!
我想了解Spring Batch是如何进行事务管理的。这不是一个技术问题,而是一个概念性的问题:Spring Batch使用什么方法?这种方法的后果是什么? 让我试着澄清一下这个问题。例如,在TaskletStep中,我看到步骤执行通常如下所示: 准备步骤元数据的几个JobRepository事务 每一块要处理的业务事务 更多JobRepository事务,用区块处理的结果更新步骤元数据 这似乎是