我有一个 Spring 批处理作业,其中 ItemWriter 发布到 Web 服务。我有一个必须转换并发布到 Web 服务的输入文件,我没有直接访问数据库的权限。
我的问题是,我应该如何处理网络服务的失败响应?例如,如果我正在处理一条记录并将其发送到 Web 服务,但 Web 服务响应“失败 - 找不到该 ID” 我应该如何记录这条记录在 Spring 失败(从商业意义上讲)批?我希望抛出一个可跳过的异常,以便在 Spring Batch Admin 中记录一个写跳过,但我看到当我从项目编写器中抛出错误时,该 block 会自动回滚。然后,当 block 被重新处理时,记录将第二次发送到 Web 服务。
对于这种场景有什么建议?诸如将不良记录发送给另一个将其记录在单独位置的项目编写器之类的东西?或者有没有办法在不回滚的情况下将其记录为写跳过?我意识到这可能是我们应用程序中的一个更大的架构问题,并且愿意接受建议。
谢谢!
最佳答案
当在 Spring Batch 中的 ItemWriter
中发生错误时,我们回滚整个 block ,将该 block 中的项目的提交间隔设置为 1,然后一项一项地重试,以便我们可以识别导致问题的单个项目(我们第一次不知道,因为我们将项目列表传递给 write 方法)。虽然这适用于事务性 ItemWriter
实现(以及那些我们可以像平面文件一样处理的实现),但它显然在非事务性选项方面存在一些问题。另一件需要注意的事情是你可以关闭回滚,但这真的不是你的问题。不是不能关闭rollback,而是rollback 什么都不做。关闭回滚仍将重试先前成功处理的项目。它只是表示可以重新编写它们。
不知道您的完整用例(以及数量),我想到了几个选项:
- 将 block 大小设置为 1 - 将项目分块的主要驱动因素之一是您可以在写入时获得的优化。批处理 JDBC 写入。将所有行写入单个 block 中的文件。但是,如果您必须为每个项目调用一次 Web 服务,则调用 Web 服务不会获得这种好处。虽然您显然会在作业存储库的数据存储上承受更高的负载,但如果这不是问题,此选项将允许您使用 Spring Batch 提供的常规跳过/重试逻辑,而无需重新发送之前成功的消息。<
- 自行处理异常 - 由于您显然已经编写了自己的
ItemWriter
实现,因此您可以自行处理异常。只要您不将其扔出编写器,Spring Batch 就不会执行任何操作。
关于spring-batch - 如何处理Spring Batch的ItemWriter中的Web Service错误响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25894871/