Spring Data MongoDB-Transaktionen

1. Übersicht

Ab Version 4.0 unterstützt MongoDB ACID-Transaktionen mit mehreren Dokumenten. Und Spring Data Lovelace bietet jetzt Unterstützung für diese nativen MongoDB Transaktionen .

In diesem Tutorial werden wir die Unterstützung von Spring Data MongoDB für synchrone und reaktive Transaktionen erläutern.

Wir werden uns auch Spring Data TransactionTemplate ansehen, um Unterstützung für nicht native Transaktionen zu erhalten.

Eine Einführung in dieses Spring Data-Modul finden Sie in unserer Einführung.

2. Richten Sie MongoDB 4.0 ein

Zuerst müssen wir die neueste MongoDB einrichten, um die Unterstützung für neue native Transaktionen zu testen.

Um loszulegen, müssen wir die neueste Version aus dem MongoDB Download Center herunterladen.

Als nächstes starten wir den Mongod- Dienst über die Befehlszeile:

mongod --replSet rs0

Zum Schluss das Replikatset initiieren - falls noch nicht geschehen:

mongo --eval "rs.initiate()"

Beachten Sie, dass MongoDB derzeit Transaktionen über einen Replikatsatz unterstützt.

3. Maven-Konfiguration

Als nächstes müssen wir unserer pom.xml die folgenden Abhängigkeiten hinzufügen :

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

Die neueste Version der Bibliothek finden Sie im Central Repository

4. MongoDB-Konfiguration

Schauen wir uns nun unsere Konfiguration an:

@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); } }

Beachten Sie, dass wir MongoTransactionManager in unserer Konfiguration registrieren müssen , um native MongoDB-Transaktionen zu aktivieren, da diese standardmäßig deaktiviert sind.

5. Synchrone Transaktionen

Nachdem wir die Konfiguration abgeschlossen haben, müssen wir nur noch unsere Methode mit @Transactional kommentieren , um native MongoDB-Transaktionen zu verwenden .

Alles innerhalb der mit Anmerkungen versehenen Methode wird in einer Transaktion ausgeführt:

@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)); }

Beachten Sie, dass wir den Befehl listCollections nicht in einer Transaktion mit mehreren Dokumenten verwenden können - zum Beispiel:

@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)); } }

In diesem Beispiel wird eine MongoTransactionException ausgelöst, da wir die collectionExists () -Methode verwendet haben.

6. TransactionTemplate

Wir haben gesehen, wie Spring Data neue native MongoDB-Transaktionen unterstützt. Darüber hinaus bietet Spring Data auch die nicht native Option.

Mit Spring Data TransactionTemplate können wir nicht native Transaktionen ausführen :

@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)); }

Wir müssen gesetzt SessionSynchronization zu IMMER nicht-native Spring Data - Transaktionen zu verwenden.

7. Reaktive Transaktionen

Abschließend werfen wir einen Blick auf die Spring Data-Unterstützung für reaktive MongoDB-Transaktionen .

Wir müssen der pom.xml einige weitere Abhängigkeiten hinzufügen , um mit reaktiver MongoDB arbeiten zu können:

 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 

Die Abhängigkeiten von Mongodb-Treiber-Reaktivströmen, Mongodb-Treiber-Synchronisierung und Reaktortest sind auf Maven Central verfügbar.

Und natürlich müssen wir unsere Reactive MongoDB konfigurieren:

@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"; } }

Um Transaktionen in reaktiven MongoDB zu verwenden, müssen wir die inTransaction () -Methode in ReactiveMongoOperations verwenden :

@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))); }

Weitere Informationen zu reaktiven Repositorys in Spring Data finden Sie hier.

8. Fazit

In diesem Artikel haben wir gelernt, wie native und nicht native MongoDB-Transaktionen mit Spring Data verwendet werden.

Der vollständige Quellcode für die Beispiele ist auf GitHub verfügbar.