sql >> Database >  >> NoSQL >> MongoDB

Spring Data MongoDB-transacties

1. Overzicht

Vanaf release 4.0 ondersteunt MongoDB ACID-transacties met meerdere documenten. En Spring Data Lovelace biedt nu ondersteuning voor deze native MongoDB-transacties .

In deze zelfstudie bespreken we Spring Data MongoDB-ondersteuning voor synchrone en reactieve transacties.

We bekijken ook Spring Data TransactionTemplate voor ondersteuning van niet-native transacties.

Bekijk onze inleidende beschrijving voor een inleiding tot deze Spring Data-module.

2. MongoDB 4.0 instellen

Eerst moeten we de nieuwste MongoDB instellen om de nieuwe ondersteuning voor native transacties te proberen.

Om te beginnen, moeten we de nieuwste versie downloaden van het MongoDB Download Center.

Vervolgens beginnen we mongod service via de opdrachtregel:

mongod --replSet rs0

Start ten slotte de replicaset - als dat nog niet het geval is:

mongo --eval "rs.initiate()"

Merk op dat MongoDB momenteel transacties via een replicaset ondersteunt.

3. Maven-configuratie

Vervolgens moeten we de volgende afhankelijkheden toevoegen aan onze pom.xml :

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>3.0.3.RELEASE</version>
</dependency>

De nieuwste release van de bibliotheek is te vinden op de Centrale Repository

4. MongoDB-configuratie

Laten we nu eens kijken naar onze configuratie:

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

Merk op dat we MongoTransactionManager moeten registreren in onze configuratie om native MongoDB-transacties in te schakelen omdat ze standaard zijn uitgeschakeld.

5. Synchrone transacties

Nadat we de configuratie hebben voltooid, hoeven we alleen maar native MongoDB-transacties te gebruiken:onze methode annoteren met @Transactional .

Alles binnen de geannoteerde methode wordt in één transactie uitgevoerd:

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

Houd er rekening mee dat we listCollections niet kunnen gebruiken commando binnen een transactie met meerdere documenten – bijvoorbeeld:

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

Dit voorbeeld genereert een MongoTransactionException zoals we de collectionExists() . gebruikten methode.

6. TransactionTemplate

We hebben gezien hoe Spring Data nieuwe native MongoDB-transacties ondersteunt. Daarnaast biedt Spring Data ook de niet-native optie.

We kunnen niet-native transacties uitvoeren met 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));
}

We moeten SessionSynchronization instellen naar ALTIJD om niet-eigen Spring Data-transacties te gebruiken.

7. Reactieve transacties

Ten slotte bekijken we Spring Data-ondersteuning voor MongoDB-reactieve transacties .

We moeten nog een paar afhankelijkheden toevoegen aan de pom.xml om te werken met reactieve 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>

De mongodb-driver-reactivestreams, mongodb-driver-sync en reactor-test-afhankelijkheden zijn beschikbaar op Maven Central.

En natuurlijk moeten we onze Reactive MongoDB configureren:

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

Om transacties in reactieve MongoDB te gebruiken, moeten we de inTransaction() . gebruiken methode in 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)));
}

Meer informatie over reactieve opslagplaatsen in Spring Data is hier beschikbaar.


  1. Kan geen werkend meteor.js-project maken op een zwervende doos

  2. MySQL Master-Slave-replicatie instellen op Ubuntu 18.04

  3. Is er een manier om MongoDB-shell-uitvoer 'mooi' af te drukken naar een bestand?

  4. CouchDB vs. MongoDB:10 dingen die je moet weten