Skip to content

Commit 549c1ef

Browse files
quafffmbenhassine
authored andcommitted
Add version to delete sql for optimistic locking
Signed-off-by: Yanming Zhou <[email protected]>
1 parent 782735a commit 549c1ef

File tree

4 files changed

+34
-8
lines changed

4 files changed

+34
-8
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobExecutionDao.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ SELECT COUNT(*)
144144

145145
private static final String DELETE_JOB_EXECUTION = """
146146
DELETE FROM %PREFIX%JOB_EXECUTION
147-
WHERE JOB_EXECUTION_ID = ?
147+
WHERE JOB_EXECUTION_ID = ? AND VERSION = ?
148148
""";
149149

150150
private static final String DELETE_JOB_EXECUTION_PARAMETERS = """
@@ -393,7 +393,13 @@ public void synchronizeStatus(JobExecution jobExecution) {
393393
*/
394394
@Override
395395
public void deleteJobExecution(JobExecution jobExecution) {
396-
getJdbcTemplate().update(getQuery(DELETE_JOB_EXECUTION), jobExecution.getId());
396+
int count = getJdbcTemplate().update(getQuery(DELETE_JOB_EXECUTION), jobExecution.getId(),
397+
jobExecution.getVersion());
398+
399+
if (count == 0) {
400+
throw new OptimisticLockingFailureException("Attempt to delete job execution id=" + jobExecution.getId()
401+
+ " with wrong version (" + jobExecution.getVersion() + ")");
402+
}
397403
}
398404

399405
/**

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcJobInstanceDao.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.beans.factory.InitializingBean;
3434
import org.springframework.dao.DataAccessException;
3535
import org.springframework.dao.EmptyResultDataAccessException;
36+
import org.springframework.dao.OptimisticLockingFailureException;
3637
import org.springframework.jdbc.core.ResultSetExtractor;
3738
import org.springframework.jdbc.core.RowMapper;
3839
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
@@ -118,7 +119,7 @@ SELECT COUNT(*)
118119

119120
private static final String DELETE_JOB_INSTANCE = """
120121
DELETE FROM %PREFIX%JOB_INSTANCE
121-
WHERE JOB_INSTANCE_ID = ?
122+
WHERE JOB_INSTANCE_ID = ? AND VERSION = ?
122123
""";
123124

124125
private DataFieldMaxValueIncrementer jobInstanceIncrementer;
@@ -279,7 +280,13 @@ public long getJobInstanceCount(@Nullable String jobName) throws NoSuchJobExcept
279280
*/
280281
@Override
281282
public void deleteJobInstance(JobInstance jobInstance) {
282-
getJdbcTemplate().update(getQuery(DELETE_JOB_INSTANCE), jobInstance.getId());
283+
int count = getJdbcTemplate().update(getQuery(DELETE_JOB_INSTANCE), jobInstance.getId(),
284+
jobInstance.getVersion());
285+
286+
if (count == 0) {
287+
throw new OptimisticLockingFailureException("Attempt to delete job instance id=" + jobInstance.getId()
288+
+ " with wrong version (" + jobInstance.getVersion() + ")");
289+
}
283290
}
284291

285292
/**

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/jdbc/JdbcStepExecutionDao.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ SELECT COUNT(*)
117117

118118
private static final String DELETE_STEP_EXECUTION = """
119119
DELETE FROM %PREFIX%STEP_EXECUTION
120-
WHERE STEP_EXECUTION_ID = ?
120+
WHERE STEP_EXECUTION_ID = ? and VERSION = ?
121121
""";
122122

123123
private static final Comparator<StepExecution> BY_CREATE_TIME_DESC_ID_DESC = Comparator
@@ -381,7 +381,13 @@ public long countStepExecutions(JobInstance jobInstance, String stepName) {
381381
*/
382382
@Override
383383
public void deleteStepExecution(StepExecution stepExecution) {
384-
getJdbcTemplate().update(getQuery(DELETE_STEP_EXECUTION), stepExecution.getId());
384+
int count = getJdbcTemplate().update(getQuery(DELETE_STEP_EXECUTION), stepExecution.getId(),
385+
stepExecution.getVersion());
386+
387+
if (count == 0) {
388+
throw new OptimisticLockingFailureException("Attempt to delete step execution id=" + stepExecution.getId()
389+
+ " with wrong version (" + stepExecution.getVersion() + ")");
390+
}
385391
}
386392

387393
private static class StepExecutionRowMapper implements RowMapper<StepExecution> {

spring-batch-test/src/main/java/org/springframework/batch/test/JobRepositoryTestUtils.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2023 the original author or authors.
2+
* Copyright 2006-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
3131
import org.springframework.batch.core.repository.JobRepository;
3232
import org.springframework.batch.core.repository.JobRestartException;
33+
import org.springframework.dao.OptimisticLockingFailureException;
3334
import org.springframework.lang.Nullable;
3435

3536
/**
@@ -39,6 +40,7 @@
3940
*
4041
* @author Dave Syer
4142
* @author Mahmoud Ben Hassine
43+
* @author Yanming Zhou
4244
*/
4345
public class JobRepositoryTestUtils {
4446

@@ -136,7 +138,12 @@ public void removeJobExecutions(Collection<JobExecution> jobExecutions) {
136138
removeJobExecution(jobExecution);
137139
}
138140
for (JobExecution jobExecution : jobExecutions) {
139-
this.jobRepository.deleteJobInstance(jobExecution.getJobInstance());
141+
try {
142+
this.jobRepository.deleteJobInstance(jobExecution.getJobInstance());
143+
}
144+
catch (OptimisticLockingFailureException ignore) {
145+
// same job instance may be already deleted
146+
}
140147
}
141148
}
142149

0 commit comments

Comments
 (0)