データ]

  • リンク:/tag/mongodb/[MongoDB]


1概要

4.0リリースから、MongoDBはマルチドキュメントACIDトランザクションをサポートします。そして、Spring Data Lovelaceは、これらのネイティブMongoDBトランザクションをサポートしています。

このチュートリアルでは、Spring Data MongoDBによる同期トランザクションとリアクティブトランザクションのサポートについて説明します。

非ネイティブトランザクションのサポートについては、Spring DataのTransactionTemplateもご覧ください。

このSpring Dataモジュールの紹介については、https://www.baeldung.com/spring-data-mongodb-tutorial[Introduction write-up]をご覧ください。


2 MongoDB 4.0のセットアップ

まず、新しいネイティブトランザクションのサポートを試すために、最新のMongoDBをセットアップする必要があります。

始めるには、https://www.mongodb.com/download-center?initial=true#atlas[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>2.1.0.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-releasetrain</artifactId>
    <version>Lovelace-M3</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

マイルストーンリポジトリを

pom.xml

にも追加する必要があることに注意してください。

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

このライブラリの最新版はhttps://search.maven.org/search?q=g:org.springframework.data%20AND%20a:spring-data-mongodb[中央リポジトリ]にあります。


4 MongoDBの設定

それでは、構成を見てみましょう。

@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.repository")
public class MongoTransactionConfig extends AbstractMongoConfiguration{

    @Bean
    MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

    @Override
    protected String getDatabaseName() {
        return "test";
    }

    @Override
    public MongoClient mongoClient() {
        return new MongoClient("127.0.0.1", 27017);
    }
}

ネイティブMongoDBトランザクションはデフォルトで無効になっているため、有効にするには

MongoTransactionManager

** を設定に登録する必要があります。

5.同期トランザクション

設定が完了したら、ネイティブのMongoDBトランザクションを使用するために必要なことはすべて、メソッドに

__

@Transactional ** と注釈を付けることです。

注釈付きメソッド内のすべてのものが1つのトランザクションで実行されます。

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

この例では、

collectionExists()

メソッドを使用したときに

MongoTransactionException

がスローされます。

マルチドキュメントトランザクションの中で

count

を実行することもできません。

@Test(expected = MongoCommandException.class)
@Transactional
public void whenCountDuringMongoTransaction__thenException() {
    userRepository.save(new User("John", 30));
    userRepository.save(new User("Ringo", 35));
    userRepository.count();
}

しかし、単純なクエリでこの問題を回避してから、結果のリストのサイズを取得することができます。

@Test
@Transactional
public void whenQueryDuringMongoTransaction__thenSuccess() {
    userRepository.save(new User("Jane", 20));
    userRepository.save(new User("Nick", 33));
    List<User> users = mongoTemplate.find(new Query(), User.class);

    assertTrue(users.size() > 1);
}


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

ネイティブではないSpring Dataトランザクションを使用するには、

SessionSynchronization



ALWAYS

に設定する必要があります。


7. 反応性トランザクション

最後に、

MongoDBのリアクティブトランザクションに対するSpring Dataのサポート

を見てみましょう。

リアクティブMongoDBを使用するには、

pom.xml

にさらにいくつかの依存関係を追加する必要があります。

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-reactivestreams</artifactId>
    <version>1.9.2</version>
</dependency>

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-test</artifactId>
    <version>3.2.0.RELEASE</version>
    <scope>test</scope>
</dependency>


mongodb-driver-reactivestreams

およびhttps://search.maven.org/search?q=a:reactor-test%20AND% 20g:Maven Centralにio.projectreactor[reactor-test]の依存関係があります。

そしてもちろん、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でトランザクションを使用するには、

ReactiveMongoOperations



inTransaction()

メソッドを使用する必要があります。

@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のリアクティブリポジトリの詳細については、https://www.baeldung.com/spring-data-mongodb-reactive[こちら]をご覧ください。


8結論

この記事では、Spring Dataを使用してネイティブおよび非ネイティブのMongoDBトランザクションを使用する方法を学びました。

例の完全なソースコードが利用可能です

https://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-mongodb

GitHubで。