MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Spring Data MongoDB транзакции

1. Прегледа

Започвайки от версия 4.0, MongoDB поддържа многодокументни ACID транзакции. И Spring Data Lovelace вече предоставя поддръжка за тези собствени транзакции на MongoDB .

В този урок ще обсъдим поддръжката на Spring Data MongoDB за синхронни и реактивни транзакции.

Ще разгледаме и Spring Data TransactionTemplate за поддръжка на транзакции, които не са местни.

За въведение в този модул Spring Data, разгледайте нашия уводен текст.

2. Настройте MongoDB 4.0

Първо, ще трябва да настроим най-новата MongoDB, за да изпробваме новата поддръжка за транзакции.

За да започнем, трябва да изтеглим най-новата версия от Центъра за изтегляне на MongoDB.

След това ще започнем mongod услуга с помощта на командния ред:

mongod --replSet rs0

И накрая, стартирайте набор от реплики – ако все още не е:

mongo --eval "rs.initiate()"

Имайте предвид, че MongoDB в момента поддържа транзакции през набор от реплики.

3. Конфигурация на Mavenа

След това трябва да добавим следните зависимости към нашия pom.xml :

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

Най-новата версия на библиотеката може да бъде намерена в Централното хранилище

4. Конфигурация на MongoDBа

Сега, нека да разгледаме нашата конфигурация:

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

Имайте предвид, че трябва да регистрираме MongoTransactionManager в нашата конфигурация, за да активирате собствените транзакции на MongoDB, тъй като те са деактивирани по подразбиране.

5. Синхронни транзакции

След като завършихме конфигурацията, всичко, което трябва да направим, за да използваме собствени транзакции на MongoDB – е да анотираме нашия метод с @Transactional .

Всичко в анотирания метод ще бъде изпълнено в една транзакция:

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

Имайте предвид, че не можем да използваме listCollections команда в транзакция с множество документи – например:

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

Този пример хвърля MongoTransactionException тъй като използвахме collectionExists() метод.

6. TransactionTemplate

Видяхме как Spring Data поддържат нова собствена транзакция на MongoDB. Освен това Spring Data предоставя и опцията, която не е местна.

Можем да извършваме транзакции, които не са местни с помощта на 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));
}

Трябва да зададем SessionSynchronization до ВИНАГИ за да използвате не-родни транзакции на Spring Data.

7. Реактивни транзакциии

И накрая, ще разгледаме Поддръжката на Spring Data за реактивни транзакции на MongoDB .

Ще трябва да добавим още няколко зависимости към pom.xml за работа с реактивен 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>

Зависимостите mongodb-driver-reactivestreams, mongodb-driver-sync и reactor-test са налични в Maven Central.

И разбира се, трябва да конфигурираме нашия 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";
    }
}

За да използваме транзакции в реактивна MongoDB, трябва да използваме inTransaction() метод в 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)));
}

Повече информация за реактивните хранилища в Spring Data е налична тук.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Настъпи изчакване след 30 000 ms избор на сървър с помощта на CompositeServerSelector

  2. Запитване на данни от MongoDB с помощта на GraphQL в Django:Get-Go (1)

  3. Персонализирани низове за потребителска връзка за екземпляри на MongoDB с удостоверяване

  4. Използването на findOne в цикъл отнема твърде много време в Node.js

  5. MongoDB $abs