MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Transakcje Spring Data MongoDB

1. Przegląd

Począwszy od wersji 4.0 MongoDB obsługuje wielodokumentowe transakcje ACID. I Spring Data Lovelace zapewnia teraz obsługę tych natywnych transakcji MongoDB .

W tym samouczku omówimy obsługę Spring Data MongoDB dla transakcji synchronicznych i reaktywnych.

Przyjrzymy się również Spring Data TransactionTemplate do obsługi transakcji innych niż natywne.

Aby zapoznać się z wprowadzeniem do tego modułu Spring Data, zapoznaj się z naszym wstępnym opisem.

2. Skonfiguruj MongoDB 4.0

Najpierw musimy skonfigurować najnowszą bazę danych MongoDB, aby wypróbować nową obsługę transakcji natywnych.

Aby rozpocząć, musimy pobrać najnowszą wersję z Centrum pobierania MongoDB.

Następnie zaczniemy mongod usługa za pomocą wiersza poleceń:

mongod --replSet rs0

Na koniec zainicjuj zestaw replik — jeśli jeszcze nie:

mongo --eval "rs.initiate()"

Zwróć uwagę, że MongoDB obecnie obsługuje transakcje na zestawie replik.

3. Konfiguracja Maven

Następnie musimy dodać następujące zależności do naszego pom.xml :

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

Najnowszą wersję biblioteki można znaleźć w Centralnym Repozytorium

4. Konfiguracja MongoDB

Przyjrzyjmy się teraz naszej konfiguracji:

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

Pamiętaj, że musimy zarejestrować MongoTransactionManager w naszej konfiguracji, aby włączyć natywne transakcje MongoDB, ponieważ są one domyślnie wyłączone.

5. Transakcje synchroniczne

Po zakończeniu konfiguracji wszystko, co musimy zrobić, aby korzystać z natywnych transakcji MongoDB – to opisać naszą metodę za pomocą @Transakcyjne .

Wszystko w opisanej metodzie zostanie wykonane w jednej transakcji:

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

Pamiętaj, że nie możemy używać listCollections polecenie wewnątrz transakcji wielodokumentowej – na przykład:

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

Ten przykład rzuca MongoTransactionException ponieważ użyliśmy metody collectionExists() metoda.

6. Szablon transakcji

Widzieliśmy, jak Spring Data obsługuje nową transakcję natywną MongoDB. Dodatkowo Spring Data zapewnia również opcję nienatywną.

Możemy przeprowadzać transakcje inne niż natywne za pomocą 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));
}

Musimy ustawić SessionSynchronization do ZAWSZE używać nienatywnych transakcji Spring Data.

7. Transakcje reaktywne

Na koniec przyjrzymy się obsłudze Spring Data dla reaktywnych transakcji MongoDB .

Musimy dodać kilka dodatkowych zależności do pliku pom.xml do pracy z reaktywnym 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>

Zależności mongodb-driver-reactivestreams, mongodb-driver-sync i reaktor-test są dostępne w Maven Central.

I oczywiście musimy skonfigurować naszą reaktywną 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";
    }
}

Aby używać transakcji w reaktywnej MongoDB, musimy użyć inTransaction() metoda w 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)));
}

Więcej informacji na temat reaktywnych repozytoriów w Spring Data jest dostępnych tutaj.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Co oznacza zbyt wiele opcji pozycyjnych podczas eksportu mongo?

  2. Jak usunąć wszystkie dokumenty z kolekcji za pomocą Mongoose?

  3. Rejestrowanie zapytań MongoDB za pomocą Spring Boot

  4. Stwórz stronę internetową sklepu spożywczego za pomocą Angular, NodeJS, Express i MongoDB

  5. Jak skutecznie zarządzać dużymi bazami danych