1. Tổng quan
Bắt đầu từ bản phát hành 4.0, MongoDB hỗ trợ các giao dịch ACID đa tài liệu. Và Spring Data Lovelace hiện cung cấp hỗ trợ cho các giao dịch MongoDB gốc này .
Trong hướng dẫn này, chúng ta sẽ thảo luận về hỗ trợ Spring Data MongoDB cho các giao dịch đồng bộ và phản ứng.
Chúng tôi cũng sẽ xem xét dữ liệu mùa xuân TransactionTemplate để được hỗ trợ giao dịch không phải gốc.
Để có phần giới thiệu về mô-đun Dữ liệu mùa xuân này, hãy xem phần viết giới thiệu của chúng tôi.
2. Thiết lập MongoDB 4.0
Trước tiên, chúng tôi sẽ cần thiết lập MongoDB mới nhất để thử hỗ trợ giao dịch gốc mới.
Để bắt đầu, chúng tôi phải tải xuống phiên bản mới nhất từ Trung tâm Tải xuống MongoDB.
Tiếp theo, chúng ta sẽ bắt đầu mongod dịch vụ sử dụng dòng lệnh:
mongod --replSet rs0
Cuối cùng, khởi tạo tập hợp bản sao - nếu chưa:
mongo --eval "rs.initiate()"
Lưu ý rằng MongoDB hiện hỗ trợ các giao dịch trên một tập hợp bản sao.
3. Cấu hình Maven
Tiếp theo, chúng tôi cần thêm các phần phụ thuộc sau vào pom.xml của chúng tôi :
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
Bản phát hành mới nhất của thư viện có thể được tìm thấy trên Kho lưu trữ Trung tâm
4. Cấu hình MongoDB
Bây giờ, hãy xem cấu hình của chúng tôi:
@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);
}
}
Lưu ý rằng chúng tôi cần đăng ký MongoTransactionManager trong cấu hình của chúng tôi để kích hoạt các giao dịch MongoDB gốc vì chúng bị tắt theo mặc định.
5. Giao dịch đồng bộ
Sau khi chúng tôi hoàn thành cấu hình, tất cả những gì chúng tôi cần làm để sử dụng các giao dịch MongoDB gốc - là chú thích phương thức của chúng tôi với @Transactional .
Mọi thứ bên trong phương thức được chú thích sẽ được thực hiện trong một giao dịch:
@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));
}
Lưu ý rằng chúng tôi không thể sử dụng listCollections lệnh bên trong một giao dịch nhiều tài liệu - ví dụ:
@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));
}
}
Ví dụ này ném một MongoTransactionException khi chúng tôi sử dụng collectionExists () phương pháp.
6. TransactionTemplate
Chúng tôi đã thấy cách Spring Data hỗ trợ giao dịch gốc MongoDB mới. Ngoài ra, Spring Data cũng cung cấp tùy chọn không phải gốc.
Chúng tôi có thể thực hiện các giao dịch không phải gốc bằng cách sử dụng 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));
}
Chúng tôi cần đặt SessionSynchronization thành LUÔN LUÔN để sử dụng các giao dịch Dữ liệu mùa xuân không phải gốc.
7. Giao dịch phản ứng
Cuối cùng, chúng ta sẽ xem xét Hỗ trợ dữ liệu mùa xuân cho các giao dịch phản ứng MongoDB .
Chúng tôi sẽ cần thêm một số phụ thuộc khác vào pom.xml để làm việc với MongoDB phản ứng:
<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>
Các phần phụ thuộc mongodb-driver-Reativestreams, mongodb-driver-sync và reactor-test có sẵn trên Maven Central.
Và tất nhiên, chúng ta cần định cấu hình Reactive MongoDB của mình:
@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";
}
}
Để sử dụng các giao dịch trong MongoDB phản ứng, chúng tôi cần sử dụng inTransaction () trong 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)));
}
Thông tin thêm về kho lưu trữ phản ứng trong Dữ liệu mùa xuân có sẵn tại đây.