How to use mongodb transactions in Spring Boot
9577
MongoDB introduced much-awaited transactions feature in their 4.0 release is called 'Multi-Document transactions'.
What is Transaction
In MongoDB, each and every operation or query may modify a single document or multiple documents, For example, updateOne() operation updates one document is atomic, if we try to modify multiple documents by using a single operation like updateMany() is not atomic because of multiple documents are modifying in the collection. If we want to make multiple write operations as atomic we need a transaction.
In MongoDB 4.0 Multi-Document transactions support available for atomic operation on multiple writes.
Properties of Transaction
- When the transaction has committed all data operations on the transaction will commit automatically.
- If any operation fails, the transaction will fail.
- When the transaction has failed all data operations on the transaction will roll back automatically.
- Until transaction committed no write operation data will be exposed to the outside world.
In Version 4.0, Multi-Document transactions supports transaction on replica sets.
In Version 4.2, Multi-Document transactions supports transaction on replica sets, sharded clusters .
Operation on Transaction
- CRUD operation is allowed in a transaction.
- Write to a capped collection is also allowed.
- Write to system.* collections.
- For cursors created outside of a transaction, we can not use it inside of a transaction.
- For cursors created inside of a transaction, we can use in outside of a transaction also.
Spring MongoDB configuration
@Configuration
static class Config extends AbstractMongoConfiguration {
@Bean
MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
// ...
}
Spring Service
By adding @Transactional to the service method, it automatically enables transactions to the below method, if any error occurs it reverts all mongo write operations.
@Transactional
public void addUsers() {
userRepository.save(new User("Alex"));
roleRepository.save(new User("Admin"));
}