sql >> Databasteknik >  >> NoSQL >> MongoDB

Vårdata MongoDB-transaktioner

1. Översikt

Från och med version 4.0 stöder MongoDB ACID-transaktioner med flera dokument. Och, Spring Data Lovelace ger nu stöd för dessa inbyggda MongoDB-transaktioner .

I den här handledningen kommer vi att diskutera Spring Data MongoDB-stöd för synkrona och reaktiva transaktioner.

Vi ska också ta en titt på Spring Data TransactionTemplate för icke-inbyggt transaktionsstöd.

För en introduktion till denna Spring Data-modul, ta en titt på vår inledande beskrivning.

2. Konfigurera MongoDB 4.0

Först måste vi konfigurera senaste MongoDB för att prova det nya inbyggda transaktionsstödet.

För att komma igång måste vi ladda ner den senaste versionen från MongoDB Download Center.

Därefter börjar vi mongod tjänst med kommandoraden:

mongod --replSet rs0

Slutligen, initiera replikuppsättningen – om inte redan:

mongo --eval "rs.initiate()"

Observera att MongoDB för närvarande stöder transaktioner över en replikuppsättning.

3. Maven-konfiguration

Därefter måste vi lägga till följande beroenden till vår pom.xml :

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

Den senaste versionen av biblioteket finns på Central Repository

4. MongoDB-konfiguration

Låt oss nu ta en titt på vår 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);
    }
}

Observera att vi måste registrera MongoTransactionManager i vår konfiguration för att aktivera inbyggda MongoDB-transaktioner eftersom de är inaktiverade som standard.

5. Synkrona transaktioner

Efter att vi avslutat konfigurationen behöver vi allt vi behöver göra för att använda inbyggda MongoDB-transaktioner – att kommentera vår metod med @Transactional .

Allt inom den kommenterade metoden kommer att exekveras i en 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));
}

Observera att vi inte kan använda listCollections kommando i en transaktion med flera dokument – ​​till exempel:

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

Det här exemplet ger en MongoTransactionException som vi använde collectionExists() metod.

6. Transaktionsmall

Vi såg hur Spring Data stödjer nya MongoDB-transaktioner. Dessutom tillhandahåller Spring Data också alternativet icke-inbyggt.

Vi kan utföra icke-inbyggda transaktioner med 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 måste ställa in SessionSynchronization till ALLTID för att använda icke-infödda Spring Data-transaktioner.

7. Reaktiva transaktioner

Slutligen ska vi ta en titt på Spring Data-stöd för MongoDB-reaktiva transaktioner .

Vi måste lägga till några fler beroenden till pom.xml att arbeta 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>

Beroendena mongodb-driver-reactivestreams, mongodb-driver-sync och reactor-test är tillgängliga på Maven Central.

Och naturligtvis måste vi konfigurera vår 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";
    }
}

För att använda transaktioner i reaktiv MongoDB måste vi använda inTransaction() metod 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)));
}

Mer information om reaktiva förvar i Spring Data finns här.


  1. Användning av ServiceStack.Redis.Sentinel

  2. Tips för att uppgradera Percona Server för MongoDB

  3. Kraftigt nedgång i prestanda med MongoDB Change Streams

  4. MongoDB returnerar True om dokumentet finns