我必须按如下方式编写Spring Batch作业:
(欢迎评论该工作结构,但不是问题。)
在第1步中,我想在加载后将XML文件移动到另一个目录。我希望尽可能通过写入登台表来“事务”。也就是说,对暂存和文件移动的写入都成功,或者两者都没有。
我认为这是必要的,因为如果(A)暂存写入发生但文件没有移动,下一次运行将再次拾取文件并再次处理它,(B)如果文件被移动但是暂存写入了没有发生,那么我们将错过该文件的处理。
此接口的要求全部与健壮性有关。我知道我可以放一个步骤执行监听器来移动所有文件,但我希望这种方法可以保证我们不会错过处理数据并且永远不会处理相同的文件两次。
部分困难在于我使用MultiResourceItemReader
。我读到ChunkListener.beforeChunk()
作为块事务的一部分发生,所以我尝试创建一个自定义块CompletionPolicy
以在每次更改资源(文件)名称后强制完成块,但我无法得到它上班。在任何情况下,我都需要一个afterChunk()
监听器,这不是交易的一部分。
我将就我的具体问题或如何在Spring Batch中强力处理文件的专家解释提供任何指导(我只是在学习)。谢谢!
答案 0 :(得分:1)
我现在有类似的弹簧批处理。
春季批次符合您的要求。
我建议在这里开始使用spring集成。 在Spring集成中,您可以配置为监视文件夹,然后使其触发批处理作业。 official documentation中有很好的例子。
然后你应该使用强大的弹簧批概念 - 识别参数。 Spring批处理作业使用唯一参数运行,如果您将此参数作为标识,则不能使用相同参数生成其他作业(尽管您可以重新启动原始作业)。
/**
* Add a new String parameter for the given key.
*
* @param key - parameter accessor.
* @param parameter - runtime parameter
* @param identifying - indicates if the parameter is used as part of identifying a job instance
* @return a reference to this object.
*/
public JobParametersBuilder addString(String key, String parameter, boolean identifying) {
parameterMap.put(key, new JobParameter(parameter, identifying));
return this;
}
所以在这里你需要问问自己,批处理作业的唯一识别限制是什么?我会建议它的完整文件路径。但是你需要确保没有人提供具有相同文件名的不同文件。 此外,spring集成可以查看应用程序是否已经看到文件并忽略它。请检查documentation on AcceptOnceFileListFilter。
如果您想要保证'交易类似'批处理逻辑 - 然后不要将它放入Listeners中,创建一个特定的步骤来移动文件。听众有利于支持逻辑。 这样,如果此步骤因任何原因失败,您仍然可以修复问题并重试作业。
答案 1 :(得分:0)