Spring Data MongoDB транзакции

1. Общ преглед

Започвайки от версия 4.0, MongoDB поддържа ACID транзакции с множество документи. И Spring Data Lovelace сега осигурява поддръжка за тези родни транзакции на MongoDB .

В този урок ще обсъдим поддръжката на Spring Data MongoDB за синхронни и реактивни транзакции.

Също така ще разгледаме Spring Data TransactionTemplate за поддръжка на чужди транзакции.

За въведение в този модул Spring Data разгледайте нашето уводно писане.

2. Настройка на MongoDB 4.0

Първо, ще трябва да настроим най-новата MongoDB, за да изпробваме новата поддръжка на местни транзакции.

За да започнем, трябва да изтеглим най-новата версия от Центъра за изтегляне на MongoDB.

След това ще стартираме услугата mongod , използвайки командния ред:

mongod --replSet rs0

И накрая, инициирайте набор от реплики - ако не вече:

mongo --eval "rs.initiate()"

Обърнете внимание, че в момента MongoDB поддържа транзакции през набор от реплики.

3. Конфигурация на Maven

След това трябва да добавим следните зависимости към нашия pom.xml :

 org.springframework.data spring-data-mongodb 3.0.3.RELEASE 

Последната версия на библиотеката може да бъде намерена в Централното хранилище

4. Конфигурация на MongoDB

Сега, нека да разгледаме нашата конфигурация:

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

Имайте предвид, че трябва да регистрираме MongoTransactionManager в нашата конфигурация, за да активираме родните транзакции на MongoDB, тъй като те са деактивирани по подразбиране.

5. Синхронни транзакции

След като приключихме с конфигурацията, всичко, което трябва да направим, за да използваме собствени транзакции на MongoDB, е да анотираме метода си с @Transactional .

Всичко вътре в анотирания метод ще бъде изпълнено в една транзакция:

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

Този пример хвърля MongoTransactionException, тъй като използвахме метода collectionExists () .

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 users = mongoTemplate.find(query, User.class); assertThat(users.size(), is(1)); }

Трябва да зададем SessionSynchronization на ВИНАГИ, за да използваме чуждестранни транзакции на Spring Data.

7. Реактивни транзакции

Накрая ще разгледаме поддръжката на Spring Data за реактивни транзакции на MongoDB .

Ще трябва да добавим още няколко зависимости към pom.xml, за да работим с реактивен MongoDB:

 org.mongodb mongodb-driver-reactivestreams 4.1.0   org.mongodb mongodb-driver-sync 4.0.5   io.projectreactor reactor-test 3.2.0.RELEASE test 

Зависимостите mongodb-driver-reactivestream, mongodb-driver-sync и reactor-test зависимости са налични в Maven Central.

И разбира се, трябва да конфигурираме нашия 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, трябва да използваме метода inTransaction () в 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))); }

Повече информация за реактивните хранилища в Spring Data можете да намерите тук.

8. Заключение

В това описание научихме как да използваме естествени и чужди транзакции на MongoDB, използвайки Spring Data.

Пълният изходен код за примерите е достъпен на GitHub.