mongod --replSet rs0
データ]
リンク:/tag/mongodb/[MongoDB]
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]をご覧ください。
まず、新しいネイティブトランザクションのサポートを試すために、最新のMongoDBをセットアップする必要があります。
始めるには、https://www.mongodb.com/download-center?initial=true#atlas[MongoDBダウンロードセンター]から最新バージョンをダウンロードする必要があります。
次に、コマンドラインを使用して mongod サービスを開始します。
mongod --replSet rs0
最後に、レプリカセットを開始します - まだではない場合:
mongo --eval "rs.initiate()"
MongoDBは現在、レプリカセットを介したトランザクションをサポートしています。
次に、 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[中央リポジトリ]にあります。
それでは、構成を見てみましょう。
@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 ** を設定に登録する必要があります。
設定が完了したら、ネイティブの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);
}
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 に設定する必要があります。
最後に、 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[こちら]をご覧ください。
この記事では、Spring Dataを使用してネイティブおよび非ネイティブのMongoDBトランザクションを使用する方法を学びました。
例の完全なソースコードが利用可能です https://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-mongodb GitHubで。