Scenario:
- I am using Mongo DB 6+ version with spring boot.
@Bean
MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
@Transactional
public void save(Cart cart,Item item) {
Cart cartFromDB = cartRepo.findById(cart.getId());
if(cartFromDB!= null){
cart.setId(cartFromDB.getId());
cartRepo.save(cart);
}else{
cartRepo.save(cart);
}
itemRepo.save(item);
}
- I am using
@Transactionalto save two different document in the same transaction. - I was having Mongo DB with replica set, it worked fine without any error..
- Now Mongo DB has been changed to use sharding.
- I suspect after this change, I am getting TransientTransactionError intermittently. After couple of tries manually its getting succeeded
- When I implement retry it succeeded.
Error message:
com.mongodb.MongoCommandException: Command failed with error 13388 (StaleConfig): 'Transaction sd-ef6d-dsd-83bd-fsdfdf - dfdfdfdfdsdfdsfsd= - - :1 was aborted on statement 2 due to: an error from cluster data placement change :: caused by :: Encountered error from mongodb.cluster.local:26009 during a transaction :: caused by :: sharding status of collection mongodb.item is not currently known and needs to be recovered' on server mongos.xxxx.com:27017. The full response is {"ok": 0.0, "errmsg": "Transaction c43f42bd-ef6d-4c48-83bd-fgdfgsdfsgf - fgggeddddsksduydhdhsh= - - :1 was aborted on statement 2 due to: an error from cluster data placement change :: caused by :: Encountered error from mongodb.cluster.local:26009 during a transaction ::..... "errorLabels": ["TransientTransactionError"]}
Question:
- Is this something to do with sharding?
- Should I implement retry in the code as suggested by some other forums. eg What is a TransientTransactionError in Mongoose (or MongoDB)?
TransientTransactionErroris considered a possibly temporary and retryable error as mentioned here. So you may try to retry it manually in old style (see here) or better, and this way is recommended, to use a relatively new method:WithTransactionthat handles retry logic behind the scene. I didn't work withspring-boot, so not sure how it can be called there, so you have to investigate it additionally