Java SpringBatch:关于执行和上下文,作业重新启动是如何工作的?

Java SpringBatch:关于执行和上下文,作业重新启动是如何工作的?,java,spring,mongodb,spring-batch,Java,Spring,Mongodb,Spring Batch,因此,我有一个简单的批处理作业,只需一个步骤,其中包括一个从MongoDB读入对象的MongoItemReader,一个自定义项处理器,它现在只将“isProcessed”布尔标志设置为true,以及一个MongoItemWriter 问题是,我希望能够在服务器停机等情况下,在作业失败时将作业备份到DB,因此我实现了Mongo文档,这些文档基本上存储了JobExecution、StepExecution、JobInstance和ExecutionContext对象。它们似乎正确地创建了各自的对象

因此,我有一个简单的批处理作业,只需一个步骤,其中包括一个从MongoDB读入对象的MongoItemReader,一个自定义项处理器,它现在只将“isProcessed”布尔标志设置为true,以及一个MongoItemWriter

问题是,我希望能够在服务器停机等情况下,在作业失败时将作业备份到DB,因此我实现了Mongo文档,这些文档基本上存储了JobExecution、StepExecution、JobInstance和ExecutionContext对象。它们似乎正确地创建了各自的对象,因为我可以在将它们添加到作业存储库后使用它们重新启动作业,但它们从一开始就重新启动,而我希望它们从停止的地方开始


所以我想知道我错过了什么。失败的作业在何处存储失败时间/地点的数据?我认为readCount、readSkipCount、processSkipCount等变量与此有关,但这些变量都包含在我的StepExecution文档中,以及StepExecution类具有“get”方法的所有其他变量中。我当时认为可能是执行上下文,但对于作业和它的一个步骤来说都是空的

当作业重新启动时,实现ItemStream的有状态组件在打开调用期间接收步骤的ExecutionContext,允许它们根据上次运行重置状态。然后由组件重置状态,并在处理过程中调用ItemStreamupdate期间维护状态

因此,基于上述情况,失败的作业不会在失败时保持它的状态……它实际上是在成功时一直保持它的状态。这样,当它真的失败时,事情应该回到最后一个成功点。这让我想到


Mongo不是事务性的。您确定状态被正确持久化了吗?由于这个原因,我们没有基于Mongo的作业存储库…

我明白了,它可以清除一些东西,但是“状态”到底存储在哪里?在死刑的背景下?是的,我知道Mongo不是事务性的,但是MongoItemReader是分页的,对吗?当我重新启动一个失败的作业时,它是否应该从上次成功使用的页面重新启动?所以很明显,从我的问题来看,我不确定这个状态是否被正确地保持着,哈哈。当我从Mongo文档重新创建执行对象时,它们的状态是正确的,但是它们的执行上下文不包含任何条目。当我在完成时保存它们时,它们没有条目。正确。状态存储在ExecutionContext中。它通常被存储为JSON,所以它是人类可读的。好吧,那么在我的例子中,当我得到空的ExecutionContext对象并且我的作业结束失败时,这可能是因为它从最后一个失败的块中得到了上下文吗?也就是说,如果我以某种方式查看ExecutionContext对象以获得成功的块,那么这些对象就不会是空的?此外,我想到了一种解决方法,即让我的MongoItemReader查询只针对那些“isProcessed”标志设置为true的对象,但出于某种奇怪的原因,每次,读取器只读入查询应返回的对象数的一半。更奇怪的是,它并不总是精确的一半:如果这一半不是我的大块大小,它就会凑起来。e、 g.chunk size=100,查询应该返回500个对象,但它只读取250个对象中的300个