Spring Data MongoDB Transactions
1. Overview
Starting from the 4.0 release, MongoDB supports multi-document ACID transactions. And, Spring Data Lovelace now provides support for these native MongoDB transactions.
In this tutorial, we’ll discuss Spring Data MongoDB support for synchronous transactions.
2. Setup MongoDB 4.0
First, we’ll need to set up the latest MongoDB to try the new native transactions support.
To get started, we have to download the latest version from the MongoDB Download Center.
Next, we’ll start the MongoDB service using the command line:
mongod --replSet rs0
Finally, initiate replica set — if not already:
mongo --eval "rs.initiate()"
Note that MongoDB currently supports transactions over a replica set.
3. Maven Configuration
Next, we need to add the following dependencies to our pom.xml:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency><dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency><dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency><dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.0.6</version>
</dependency><dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>4.0.6</version>
</dependency><dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>4.0.6</version>
</dependency>
Note: Version compatibility is very important.
4. MongoDB Configuration
Now, let’s take a look at our configuration:
@Configuration
@EnableTransactionManagement
@EnableMongoRepositories
public class SpringContextConfiguration extends AbstractMongoClientConfiguration{
@Autowired
private MongoConfig mongoConfig;
@Override
@Bean
public MongoTemplate mongoTemplate(@Qualifier("mongoDbFactory") MongoDatabaseFactory mongoDbFactory,MappingMongoConverter converter) {
return new MongoTemplate(mongoDbFactory, getMongoConverter(mongoDbFactory));
}private MongoConverter getMongoConverter(MongoDatabaseFactory mongoDbFactory)
{
DefaultRefResolver dbRefResolver = new DefaultRefResolver(mongoDbFactory);
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setAutoIndexCreation(true);
mappingContext.afterPropertiesSet();
return new MappingMongoConverter(dbRefResolver, mappingContext);
}@Override
@Bean
public MongoClient mongoClient() {
String dbURI = "mongodb://" + "your_replicaset_string";
ConnectionString connectionString = new ConnectionString(dbURI);
MongoClientSettings mongoClientSettings = getMongoClientSettings(connectionString);
return MongoClients.create(mongoClientSettings);
}private MongoClientSettings getMongoClientSettings(ConnectionString connectionString) {
return MongoClientSettings.builder().applyConnectionString(connectionString).applyToConnectionPoolSettings(connectionPoolBuilder ->
connectionPoolBuilder.maxSize(10)).build();
}@Bean
@Override
public MongoDatabaseFactory mongoDbFactory() {
return new SimpleMongoClientDatabaseFactory(mongoClient(), getDatabaseName());
}@Bean
MongoTransactionManager transactionManager(
@Qualifier("mongoDbFactory") MongoDatabaseFactory mongoDbFactory) {
return new MongoTransactionManager(mongoDbFactory);
}
@Override
protected String getDatabaseName() {
return "your_database_name";
}
}
5. Synchronous Transactions
After we finished the configuration, we need to use native MongoDB transactions to annotate our method with @Transactional to execute MongoDB APIs within transaction boundaries.
@Transactional
public void saveEmpoyeeDetails() {
mongoTemplate.save(new Employee("Ashwani", 30, "Bangalore"));
if(true){
throw new MongoException("halt second save");
}
mongoTemplate.save(new Employee("Rohit", 35, "Pune"));
}public List<Employee> findEmployeeDetails(){
Query query = new Query().addCriteria(Criteria.where("name").is("Ashwani")); List<Employee> employess = mongoTemplate.find(query, Employee.class);
return employess // will return empty list if transaction is working fine.}
6. Conclusion
In this write-up, we learned how to use native MongoDB transactions using Spring Data. Tap the 👏 button and follow if you find this article gripping. Leave your comments, if you find any issue in setting up or any required details are missing.
Reference: https://spring.io/blog/2018/06/28/hands-on-mongodb-4-0-transactions-with-spring-data