Skip to content

Commit d0aef64

Browse files
committed
Retry on generating unique identifiers with MongoDB
This commit will mitigate write conflict: ``` org.springframework.dao.DataIntegrityViolationException: Command failed with error 112 (WriteConflict): 'Caused by :: Write conflict during plan execution and yielding is disabled. :: Please retry your operation or multi-document transaction.' on server xxx.mongodb.net:1026. The full response is {"errorLabels": ["TransientTransactionError"], "ok": 0.0, "errmsg": "Caused by :: Write conflict during plan execution and yielding is disabled. :: Please retry your operation or multi-document transaction.", "code": 112, "codeName": "WriteConflict", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1755758536, "i": 4}}, "signature": {"hash": {"$binary": {"base64": "xxx=", "subType": "00"}}, "keyId": xxx}}, "operationTime": {"$timestamp": {"t": 1755758536, "i": 4}}} at org.springframework.data.mongodb.core.MongoExceptionTranslator.doTranslateException(MongoExceptionTranslator.java:141) ~[spring-data-mongodb-4.5.0.jar:4.5.0] at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:74) ~[spring-data-mongodb-4.5.0.jar:4.5.0] at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:3033) ~[spring-data-mongodb-4.5.0.jar:4.5.0] at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:609) ~[spring-data-mongodb-4.5.0.jar:4.5.0] at org.springframework.batch.core.repository.dao.MongoSequenceIncrementer.nextLongValue(MongoSequenceIncrementer.java:47) ~[spring-batch-core-5.2.2.jar:5.2.2] at org.springframework.batch.core.repository.dao.MongoJobInstanceDao.createJobInstance(MongoJobInstanceDao.java:80) ~[spring-batch-core-5.2.2.jar:5.2.2] ``` Closes GH-4960 Signed-off-by: Yanming Zhou <[email protected]>
1 parent 088487b commit d0aef64

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/mongodb/MongoSequenceIncrementer.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
import com.mongodb.client.model.ReturnDocument;
2020
import org.bson.Document;
2121

22+
import org.springframework.core.retry.RetryException;
23+
import org.springframework.core.retry.RetryPolicy;
24+
import org.springframework.core.retry.RetryTemplate;
2225
import org.springframework.dao.DataAccessException;
26+
import org.springframework.dao.DataIntegrityViolationException;
2327
import org.springframework.data.mongodb.core.MongoOperations;
2428
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
2529

@@ -29,10 +33,14 @@
2933
/**
3034
* @author Mahmoud Ben Hassine
3135
* @author Christoph Strobl
36+
* @author Yanming Zhou
3237
* @since 5.2.0
3338
*/
3439
public class MongoSequenceIncrementer implements DataFieldMaxValueIncrementer {
3540

41+
private final RetryTemplate retryTemplate = new RetryTemplate(
42+
RetryPolicy.builder().includes(DataIntegrityViolationException.class).build());
43+
3644
private final MongoOperations mongoTemplate;
3745

3846
private final String sequenceName;
@@ -44,11 +52,22 @@ public MongoSequenceIncrementer(MongoOperations mongoTemplate, String sequenceNa
4452

4553
@Override
4654
public long nextLongValue() throws DataAccessException {
47-
return mongoTemplate.execute("BATCH_SEQUENCES",
48-
collection -> collection
55+
try {
56+
return retryTemplate
57+
.execute(() -> mongoTemplate.execute("BATCH_SEQUENCES", collection -> collection
4958
.findOneAndUpdate(new Document("_id", sequenceName), new Document("$inc", new Document("count", 1)),
5059
new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER))
51-
.getLong("count"));
60+
.getLong("count")));
61+
}
62+
catch (RetryException e) {
63+
Throwable cause = e.getCause();
64+
if (cause instanceof DataAccessException ex) {
65+
throw ex;
66+
}
67+
else {
68+
throw new RuntimeException("Failed to retrieve next value of sequence", e);
69+
}
70+
}
5271
}
5372

5473
@Override

0 commit comments

Comments
 (0)