1. Oversigt
Fra 4.0-udgivelsen understøtter MongoDB multi-dokument ACID-transaktioner. Og Spring Data Lovelace giver nu support til disse indbyggede MongoDB-transaktioner .
I denne øvelse vil vi diskutere Spring Data MongoDB-understøttelse af synkrone og reaktive transaktioner.
Vi tager også et kig på Spring Data TransactionTemplate for ikke-indfødte transaktioner support.
For en introduktion til dette Spring Data-modul, se vores introduktionsskrift.
2. Konfigurer MongoDB 4.0
Først skal vi konfigurere den seneste MongoDB for at prøve den nye native transaktionssupport.
For at komme i gang skal vi downloade den seneste version fra MongoDB Download Center.
Dernæst starter vi mongod tjeneste ved hjælp af kommandolinjen:
mongod --replSet rs0
Til sidst skal du starte replikasæt – hvis ikke allerede:
mongo --eval "rs.initiate()"
Bemærk, at MongoDB i øjeblikket understøtter transaktioner over et replikasæt.
3. Maven-konfiguration
Dernæst skal vi tilføje følgende afhængigheder til vores pom.xml :
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
Den seneste udgivelse af biblioteket kan findes på Central Repository
4. MongoDB-konfiguration
Lad os nu tage et kig på vores konfiguration:
@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);
}
}
Bemærk, at vi skal registrere MongoTransactionManager i vores konfiguration for at aktivere indbyggede MongoDB-transaktioner, da de er deaktiveret som standard.
5. Synkrone transaktioner
Efter vi har afsluttet konfigurationen, er alt, hvad vi skal gøre for at bruge native MongoDB-transaktioner – at annotere vores metode med @Transactional .
Alt inde i den kommenterede metode vil blive udført i én transaktion:
@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<User> users = mongoTemplate.find(query, User.class);
assertThat(users.size(), is(1));
}
Bemærk, at vi ikke kan bruge listCollections kommando inde i en multi-dokument transaktion – for eksempel:
@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));
}
}
Dette eksempel kaster en MongoTransactionException som vi brugte collectionExists() metode.
6. Transaktionsskabelon
Vi så, hvordan Spring Data understøtter ny MongoDB-indbygget transaktion. Derudover giver Spring Data også den ikke-native mulighed.
Vi kan udføre ikke-native transaktioner ved hjælp af 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<User> users = mongoTemplate.find(query, User.class);
assertThat(users.size(), is(1));
}
Vi skal indstille SessionSynchronization til ALTID at bruge ikke-native Spring Data-transaktioner.
7. Reaktive transaktioner
Til sidst vil vi tage et kig på Spring Data support for MongoDB reaktive transaktioner .
Vi bliver nødt til at tilføje et par flere afhængigheder til pom.xml at arbejde med reaktiv MongoDB:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.0.5</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.2.0.RELEASE</version>
<scope>test</scope>
</dependency>
Afhængighederne mongodb-driver-reactivestreams, mongodb-driver-sync og reactor-test er tilgængelige på Maven Central.
Og selvfølgelig skal vi konfigurere vores Reactive MongoDB:
@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";
}
}
For at bruge transaktioner i reaktiv MongoDB skal vi bruge inTransaction() metode i 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)));
}
Mere information om reaktive depoter i Spring Data er tilgængelig her.