Spring 在作业之间共享和更新对象
我有一个控制器,每个请求并行执行几个作业,如下所示:Spring 在作业之间共享和更新对象,spring,spring-batch,Spring,Spring Batch,我有一个控制器,每个请求并行执行几个作业,如下所示: @Controller @RequestMapping("/uploadjob") public class UploadJobController extends BaseController { .... @RequestMapping(value = "/uploadjob", method = RequestMethod.POST) public String runupload(@ModelAttribute("uploadP
@Controller
@RequestMapping("/uploadjob")
public class UploadJobController extends BaseController {
....
@RequestMapping(value = "/uploadjob", method = RequestMethod.POST)
public String runupload(@ModelAttribute("uploadParameters") UploadParameters uploadParameters,
BindingResult result, HttpServletRequest request){
...
for (Line i: lines){
try {
this.jobLauncher.run(this.uploadProjectDataJobNormal, jobParameters);
}
}
在某个时刻,作业从每个作业执行中不同的文件中读取元素,并复制到表中,但消除重复的元素
因为作业是并行执行的,所以在插入元素之前的每个作业中,我们查询数据库中的现有元素以避免重复。我们希望通过以下方法避免这种情况:
List<String> existingElements
但是这个对象应该由所有作业共享,并且同时由所有作业更新,所以这个对象需要是线程安全的。我在这里的不同问题中看到,解决方案可能是使用会话对象HttpSession对象来存储列表,并小心地访问该对象,以避免在作业步骤中出现争用情况
我说得对吗?是否有其他替代方案可以在不改变实际工作流程的情况下实现相同的结果 在尝试了不同的解决方案之后,我们就这样实现了。我们创建一个对象来存储要共享的对象:
public class JobCache {
private HashMap<TypeClass,Set<String>> ExistingNames;
private final UUID id;
...
我们知道这不是完全线程安全的,但在我们的环境下,这是因为工作是如何创建的
为了获取名称(即使不需要),我们使用以下方法:
synchronized(jobCache.getId()){
this.names = jobCache.getExistingNames(TypeClass.TYPE1);
}
也许这不是最理想、最优雅的解决方案,但它对我们很有效。为什么不使用Spring的缓存抽象来缓存查找?通过这种方式,缓存将保存现有元素的列表,您可以获得更多的控制权。因为我需要在作业的一个步骤中更新对象,所以缓存不是一个内容不断变化的列表
synchronized(jobCache.getId()){
this.names = jobCache.getExistingNames(TypeClass.TYPE1);
}