본문 바로가기

Backend/Spring

Spring Boot MongoDB multi-document transactions

몽고 DB 4버전부터 Multi-Document 트랜잭션을 지원한다고 합니다.

자세한 설명은 아래 몽고디비 홈페이지에서 한 번 확인해보세요.

영어가 잘 안읽히신다면 저처럼 번역 돌리고 보시면 됩니다!

특히, IMPORTANT!로 강조되어 있는 박스는 꼭 확인해보셔야 해요.

https://docs.mongodb.com/manual/core/transactions/

 

Transactions — MongoDB Manual

In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. For many scenarios, the denormalized data

docs.mongodb.com

 

Multi-Document 트랜잭션을 활용하시기 전에 아래 내용을 한 번 확인해보시고 다시 한 번 검토를 해보시는 것을 추천해드려요.

IMPORTANT!
In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. That is, for many scenarios, modeling your data appropriately will minimize the need for multi-document transactions.

For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.

중요!
대부분의 경우 다중 문서 트랜잭션은 단일 문서 쓰기보다 더 큰 성능 비용을 초래하며 다중 문서 트랜잭션의 가용성이 효과적인 스키마 설계를 대체해서는 안 됩니다. 많은 시나리오에서 비정규화된 데이터 모델(임베디드 문서 및 배열) 은 데이터 및 사용 사례에 계속 최적입니다. 즉, 많은 시나리오에서 데이터를 적절하게 모델링하면 다중 문서 트랜잭션의 필요성을 최소화할 수 있습니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려 사항을 참조 하십시오 .

위에 공유 드린 공식 홈페이지 트랜잭션 메뉴얼에 적혀 있는 문구 그대로 퍼왔어요.

Multi-Document 트랜잭션을 활용하기 전에 한 번 더 최적화된 도큐먼트 설계에 고민해보시는 것을 추천해드립니다!

 

이제 스프링 프로젝트에서 어떻게 사용하는지 볼게요.

간단한 설정으로 사용할 수 있어요.

MongoConfiguration

@Configuration
@EnableReactiveMongoAuditing
@EnableTransactionManagement
@Slf4j
public class MongoConfiguration {

  @Bean
  public ReactiveMongoTransactionManager transactionManager(ReactiveMongoDatabaseFactory factory) {
    return new ReactiveMongoTransactionManager(factory);
  }

  @Bean
  public TransactionalOperator transactionalOperator(ReactiveTransactionManager transactionManager) {
    return TransactionalOperator.create(transactionManager);
  }
}

Service Logic

@Transactional
public Mono<BookLikeOrHateResponse> likeBook(String bookId,
                                             AuthUser authUser) {
  // TODO
}

 

write 성격의 커맨드를 성공한 이후 메서드 내에서 Exception이 발생하면 실제 데이터가 반영되지 않음을 확인하실 수 있습니다.

 

단, 아래와 같은 오류를 겪는 분들이 많을거에요.

 

This MongoDB deployment does not support retryable writes.
Please add retryWrites=false to your connection string

 

대부분, 몽고디비를 standalone으로 구성하신 경우인데요.

이런 경우 Replica-Set으로 구성하셔야 합니다.

로컬 환경이나 개발 환경인 경우에도 단일노드 Replica-Set으로 구성하여 테스트하실 수 있습니다.

몽고 디비를 간단히 도커 이미지를 받아서 사용하시는 분들이 많을텐데요.

아래 링크에 도커에서 아주 아주 간단하게 Replica-Set을 구성하는 커맨드가 있으니 참고 부탁 드려요.

https://gofnrk.tistory.com/72

 

Docker MongoDB 설치, 접속

Docker로 MongoDB를 설치해보겠습니다. 1. Mongo 이미지 가져오기 docker pull mongo 2. 신규 컨테이너 생성 2-1. Mongo Standalone docker run --name mongo-container -p 27017:27017 mongo Docker 컨테이너 자..

gofnrk.tistory.com