Transactions MongoDB Spring Data

1. Vue d'ensemble

À partir de la version 4.0, MongoDB prend en charge les transactions ACID multi-documents. Et Spring Data Lovelace prend désormais en charge ces transactions MongoDB natives .

Dans ce didacticiel, nous discuterons de la prise en charge de Spring Data MongoDB pour les transactions synchrones et réactives.

Nous examinerons également Spring Data TransactionTemplate pour la prise en charge des transactions non natives.

Pour une introduction à ce module Spring Data, jetez un œil à notre article d'introduction.

2. Configurer MongoDB 4.0

Tout d'abord, nous devrons configurer la dernière version de MongoDB pour essayer la nouvelle prise en charge des transactions natives.

Pour commencer, nous devons télécharger la dernière version à partir du centre de téléchargement MongoDB.

Ensuite, nous allons démarrer le service mongod en utilisant la ligne de commande:

mongod --replSet rs0

Enfin, lancez le jeu de réplicas - si ce n'est déjà fait:

mongo --eval "rs.initiate()"

Notez que MongoDB prend actuellement en charge les transactions sur un jeu de réplicas.

3. Configuration Maven

Ensuite, nous devons ajouter les dépendances suivantes à notre pom.xml :

 org.springframework.data spring-data-mongodb 3.0.3.RELEASE 

La dernière version de la bibliothèque est disponible sur le référentiel central

4. Configuration MongoDB

Maintenant, jetons un œil à notre configuration:

@Configuration @EnableMongoRepositories(basePackages = "com.baeldung.repository") public class MongoConfig extends AbstractMongoClientConfiguration{ @Bean MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) { return new MongoTransactionManager(dbFactory); } @Override protected String getDatabaseName() { return "test"; } @Override public MongoClient mongoClient() { final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test"); final MongoClientSettings mongoClientSettings = MongoClientSettings.builder() .applyConnectionString(connectionString) .build(); return MongoClients.create(mongoClientSettings); } }

Notez que nous devons enregistrer MongoTransactionManager dans notre configuration pour activer les transactions MongoDB natives car elles sont désactivées par défaut.

5. Transactions synchrones

Une fois la configuration terminée, tout ce que nous avons à faire pour utiliser les transactions MongoDB natives est d' annoter notre méthode avec @Transactional .

Tout ce qui se trouve à l'intérieur de la méthode annotée sera exécuté en une seule transaction:

@Test @Transactional public void whenPerformMongoTransaction_thenSuccess() { userRepository.save(new User("John", 30)); userRepository.save(new User("Ringo", 35)); Query query = new Query().addCriteria(Criteria.where("name").is("John")); List users = mongoTemplate.find(query, User.class); assertThat(users.size(), is(1)); }

Notez que nous ne pouvons pas utiliser la commande listCollections dans une transaction multi-document - par exemple:

@Test(expected = MongoTransactionException.class) @Transactional public void whenListCollectionDuringMongoTransaction_thenException() { if (mongoTemplate.collectionExists(User.class)) { mongoTemplate.save(new User("John", 30)); mongoTemplate.save(new User("Ringo", 35)); } }

Cet exemple lève une exception MongoTransactionException car nous avons utilisé la méthode collectionExists () .

6. TransactionTemplate

Nous avons vu comment Spring Data prend en charge la nouvelle transaction native MongoDB. De plus, Spring Data fournit également l'option non native.

Nous pouvons effectuer des transactions non natives à l'aide de Spring Data TransactionTemplate :

@Test public void givenTransactionTemplate_whenPerformTransaction_thenSuccess() { mongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); TransactionTemplate transactionTemplate = new TransactionTemplate(mongoTransactionManager); transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { mongoTemplate.insert(new User("Kim", 20)); mongoTemplate.insert(new User("Jack", 45)); }; }); Query query = new Query().addCriteria(Criteria.where("name").is("Jack")); List users = mongoTemplate.find(query, User.class); assertThat(users.size(), is(1)); }

Nous devons définir SessionSynchronization sur ALWAYS pour utiliser des transactions Spring Data non natives.

7. Transactions réactives

Enfin, nous examinerons la prise en charge de Spring Data pour les transactions réactives MongoDB .

Nous devrons ajouter quelques dépendances supplémentaires au pom.xml pour travailler avec MongoDB réactif:

 org.mongodb mongodb-driver-reactivestreams 4.1.0   org.mongodb mongodb-driver-sync 4.0.5   io.projectreactor reactor-test 3.2.0.RELEASE test 

Les dépendances mongodb-driver-reactivestreams, mongodb-driver-sync et reactivestreams sont disponibles sur Maven Central.

Et bien sûr, nous devons configurer notre MongoDB réactif:

@Configuration @EnableReactiveMongoRepositories(basePackages = "com.baeldung.reactive.repository") public class MongoReactiveConfig extends AbstractReactiveMongoConfiguration { @Override public MongoClient reactiveMongoClient() { return MongoClients.create(); } @Override protected String getDatabaseName() { return "reactive"; } }

Pour utiliser des transactions dans MongoDB réactif, nous devons utiliser la méthode inTransaction () dans ReactiveMongoOperations :

@Autowired private ReactiveMongoOperations reactiveOps; @Test public void whenPerformTransaction_thenSuccess() { User user1 = new User("Jane", 23); User user2 = new User("John", 34); reactiveOps.inTransaction() .execute(action -> action.insert(user1) .then(action.insert(user2))); }

Plus d'informations sur les référentiels réactifs dans Spring Data sont disponibles ici.

8. Conclusion

Dans cet article, nous avons appris à utiliser les transactions MongoDB natives et non natives à l'aide de Spring Data.

Le code source complet des exemples est disponible à l'adresse over sur GitHub.