-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
Description
문제점
TransactionManager 부재가 MongoDB를 Main DB로 사용하는데에 문제점인 것 같습니다.
Spring Boot는 MongoDB용 TransactionManager를 자동으로 설정하지 않습니다.
JPA와 달리 MongoDB 트랜잭션은 추가 설정이 필요하고.
또한, MongoDB Replica Set 또는 Sharded Cluster 환경에서만 가능하다고 합니다.
따라서 아래의 방법을 도입하기 전에 MongoDB 설정을 변경할 필요가 있습니다.
Reference
https://oliveyoung.tech/2024-12-17/catalog-mongo-transaction-2/
테스트 롤백 불가
@Transactional이 작동하지 않으면 테스트 후 데이터가 자동으로 롤백되지 않아 테스트 간 데이터 오염이 발생할 것입니다.
해결 방법
1. MongoTransactionManager 설정
테스트 설정 클래스
@TestConfiguration
public class MongoTestConfig {
@Bean
@Primary
public MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
return new MongoTransactionManager(dbFactory);
}
}테스트 클래스에서 사용
@DataMongoTest
@Import(MongoTestConfig.class)
@Transactional
class ItemRepositoryTest {
@Autowired
private ItemRepository itemRepository;
@Test
void shouldSaveAndFindItem() {
Item item = new Item("001", "Test Item");
itemRepository.save(item);
Optional<Item> found = itemRepository.findById("001");
assertThat(found).isPresent();
}
}2. 수동 데이터 정리 방식 - @BeforeEach/@AfterEach 활용
@DataMongoTest
class ItemRepositoryTest {
@Autowired
private ItemRepository itemRepository;
@AfterEach
void cleanup() {
itemRepository.deleteAll();
}
@Test
void shouldSaveAndFindItem() {
// 테스트 로직
}
}3. @DirtiesContext 사용 - 컨텍스트 재생성 방식
@DataMongoTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class ItemRepositoryTest {
// 각 테스트 후 Spring 컨텍스트 재생성
}4. TestContainers 활용 - 실제 MongoDB 환경
@SpringBootTest
@Testcontainers
class ItemRepositoryIntegrationTest {
@Container
static MongoDBContainer mongoDBContainer = new MongoDBContainer("mongo:4.4")
.withReplicaSet();
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
}
@Transactional
@Test
void shouldWorkWithTransactions() {
// 실제 Replica Set 환경에서 트랜잭션 테스트
}
}권장 접근법
개발 단계별 전략
- 단위 테스트: 수동 데이터 정리 방식 사용
- 통합 테스트: MongoTransactionManager 설정 또는 TestContainers 활용
- 성능 테스트: 실제 MongoDB Replica Set 환경 구성
실용적 해결책
@DataMongoTest
class ItemRepositoryTest {
@Autowired
private TestEntityManager entityManager; // MongoDB에는 없음
@Autowired
private MongoTemplate mongoTemplate;
@BeforeEach
void setup() {
mongoTemplate.getCollection("items").deleteMany(new Document());
}
@Test
void shouldSaveItem() {
// 테스트 로직
}
}초기에는 수동 정리 방식으로 추가하고, 필요에 따라 트랜잭션 설정을 추가하는 것이 실용적일 것 같습니다.