首页 > 解决方案 > 异步 Spring Batch。通过 2 个步骤创建工作

问题描述

我需要多次调用 Web 服务并传递使用来自多个表的数据创建的数据

UI -> 控制器 -> 服务 -> (获取数据(Table1,table2)并运行一些验证) 1. 如果验证失败 - 返回错误消息并停止。2. 如果验证通过 - 调用 JobLauncher 并返回“任务启动”消息。

在异步作业中,我想到了以下两个步骤。

  1. 批量插入步骤

    • 我需要调用 DB 来查询另外 2 个表(Table3、table4)并创建一个大数据集,从之前获取的 Table1、Table2 和当前获取的 table3、table4

    • 将创建的数据集插入 table5

  2. WebServiceStep (AysncTaskExecutor)

    • 读者:从 Table5 查询
    • 处理器:为每一行调用 Web 服务。
    • 作者:更新Table5

我不知道 BulkInsertStep 是否 有资格成为BatchJob中的步骤。基本上它是 for 循环中的 for 循环中的 for 循环来创建 DTO 对象列表。读者,处理器或作家的东西很少令人困惑..

避免BulkInsertStep避免了批量插入和读取WebServiceStep,但是如果以后用户想要重新运行失败的 web 服务记录,将很难弄清楚哪些排列已经处理以及需要处理哪些排列。

请提出设计或其他方式来实现相同的目标。 要求:

  1. Webservice 调用大数据需要一些时间。所以 UI 不能等待响应。
  2. 用户可以重新运行任务,该任务处理失败的任务。

标签: springasynchronousspring-batch

解决方案


我不知道 BulkInsertStep 是否有资格成为 BatchJob 中的步骤。

我认为您绝对需要将其作为Reader-Processor-Writer. 虽然编写起来有点复杂,但它为您带来了可重启性和容错性等能力。之前我也认为这Reader-Processor-Writer是一种矫枉过正,但最终它也会导致更好的结构化和可维护的代码。

避免 BulkInsertStep 避免了批量插入和读取 WebServiceStep,但是如果以后用户想要重新运行失败的 web 服务记录,将很难弄清楚哪些排列已经处理以及需要处理哪些排列。

我以前做过类似的事情。我建议在每次调用 WebService 后将结果存储在数据库中。这就是表格的样子:

- requestId 
- requestURL
- method (GET/POST/PUT/etc.) 
- requestBody (CLOB)
- requestHeaders 
- responseCode 
- responseBody (CLOB)
- responseHeaders

有了这张表,我可以确定不会有重复的 WebService 调用。如果批处理作业失败,我可以简单地在这一步重新启动 Job 并从未完成的调用开始继续处理。

为此,您需要额外的步骤将数据转换为请求(准备它们),然后再次使用reader-processor-writerdo WebService 调用。

Webservice 调用大数据需要一些时间。所以 UI 不能等待响应。

我假设您无论如何都会在单独的线程中开始整个工作。您需要配置将使用的作业启动器ThreadPoolTaskExecutor。然后作业将异步运行。

用户可以重新运行任务,该任务处理失败的任务。

这很容易实现。你有两个选择:


推荐阅读