如何解决当两个作业尝试使用同一表时,Spring批处理锁定资源
我正在使用 Spring boot&Spring batch ,如果该表(表A)已经可以工作,我想锁定表A中的访问权限,因此我想将等待列表中的作业,直到前一个作业完成并重新启动已停止的作业。
目前,我可以使用** JobExecutionListener **的beforeJob **和** afterJob **方法停止同一个实例的作业,并在另一个作业(同一个实例)结束时重新启动它。但是我无法检查具有相同参数(访问相同表)的两个不同作业。
这是我的代码:
private void runJobB(Job parJob) throws Exception {
log.info("[Job] running ...........");
Map<String,JobParameter> confMap = new HashMap<>();
confMap.put("value",new JobParameter("label_test"));
confMap.put("time",new JobParameter(System.currentTimeMillis()));
JobParameters jobParameters = new JobParameters(confMap);
try {
jobLauncher.run(parJob,jobParameters);
} catch (Exception ex) {
log.error("job1 : " + ex.getMessage());
}
}
public class InterceptingJobExecution implements JobExecutionListener {
static private Map<Long,JobExecution> jobInformationsMap = new HashMap<>();
@Autowired
private JobExplorer jobExplorer;
@Autowired
private JobRepository jobRepository;
@Autowired
private JobOperator jobOperator;
@SneakyThrows
@Override
public void beforeJob(JobExecution jobExecution) {
log.info("Intercepting Job Excution - Before Job!");
final String locJobName = jobExecution.getJobInstance().getJobName();
final List<JobExecution> jobExecutionList = new ArrayList<>(jobExplorer.findRunningJobExecutions(locJobName));
if (jobExecutionList.size() > 1) {
for (JobExecution jobExecution1 : jobExecutionList) {
synchronized (jobExecution1) {
jobInformationsMap.put(jobExecution1.getId(),jobExecution1);
jobExecution1.setEndTime(new Date());
jobExecution1.setStatus(BatchStatus.FAILED);
jobExecution1.setExitStatus(ExitStatus.FAILED);
jobExecution1.stop();
}
}
}
}
private void restart() {
try {
final Map.Entry<Long,JobExecution> first = getFirst();
final JobExecution jobExecution = first.getValue();
synchronized (jobExecution) {
if(jobExecution.getStatus().equals(BatchStatus.STOPPING)) {
jobRepository.update(jobExecution);
jobOperator.restart(jobExecution.getId());
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
@SneakyThrows
@Override
public void afterJob(JobExecution jobExecution) {
synchronized (jobExecution) {
log.info("Intercepting Job Excution - After Job!");
if(jobInformationsMap.size() > 1) {
restart();
}
}
}
private static Map.Entry<Long,JobExecution> getFirst() {
Map.Entry<Long,JobExecution> locJobExecution = null;
Date minCreateTime = Calendar.getInstance().getTime();
for( Map.Entry<Long,JobExecution> locMap : jobInformationsMap.entrySet()) {
final Date createTime = locMap.getValue().getCreateTime();
if(minCreateTime.after(createTime)) {
minCreateTime = createTime;
locJobExecution = locMap;
}
}
jobInformationsMap.remove(locJobExecution.getKey());
return locJobExecution;
}
}
我到处搜索过,但是没有找到与我想要的内容完全匹配的东西,如果可以的话,谢谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。