Spring Data MongoDBトランザクション

データ]

  • リンク:/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で。

前の投稿:Spring @Valueのクイックガイド
次の投稿:WildFlyのデフォルトポートを変更する