개요
우아한 테크코스 프리코스 4~6주 차 오픈 미션에서 채팅 서비스를 구현하던 중,
팀원과 DB 선택을 두고 의견 차이가 생겼고, 개발 과정에서 코드 병합 충돌이 발생했습니다.
해당 갈등을 해결하기 위해 전략 패턴 구조를 설계하여 DB를 성공적으로 마이그레이션 할 수 있었습니다.
배경
프로젝트의 주제는 실시간 채팅 서비스였고, 프로젝트의 핵심 기능은 다음과 같았습니다.
- 웹 소켓 기반 실시간 채팅
- 번역 API 연동
- 채팅 데이터 저장
백엔드는 저를 포함하여 두 명이었고, 채팅 데이터를 저장할 DB 선택 과정에서 의견이 충돌했습니다.
문제 상황
팀원 의견 - MongoDB에 저장
- 채팅은 많은 데이터를 저장해야 하므로, 대용량 채팅 데이터 저장에는 MongoDB가 성능에 유리하다.
- 새로운 기술을 학습할 수 있는 기회이다.
나의 의견 - RDBMS면 충분
- 유저(User)나 채팅방(ChatRoom) 관련 데이터를 RDBMS 기반으로 개발 중이라 연동이 빠르다.
- 많은 채팅 데이터를 저장하기에 MongoDB가 유리하지만, 프로젝트가 소규모이므로 MongoDB를 사용한다고 성능의 이점이 체감되지 않을 것이다.
- 프런트와 빠르게 연동하려면 JPA가 유리하다.
- MongoDB를 다루어 본 경험이 없어, 새로운 기술을 처음부터 적용하면 연동이 늦어질 것이다.
- 데이터 정합성을 고려하려면, RDBMS가 더 좋을 것이다.
이와 같은 대화를 주고받았고, 절충안을 제안했습니다.
- 개발 초기: JPA로 기본 기능을 빠르게 구축한다.
- 개발 중반: 프런트와 연동을 진행하며, MongoDB를 학습 및 개발을 시작한다.
- 개발 후반: MongoDB로 전환한다.
MongoDB 도입으로 인한 충돌 발생
이후 본격적인 개발을 시작했습니다.
채팅 서비스에서 핵심적인 기술은 웹소켓을 활용한 채팅 시스템과 번역 API를 사용하여 채팅을 번역하는 기능이었습니다.
핵심 로직들을 연동 및 테스트해 보기 위해서는 채팅 관련 서비스를 빠르게 작성해야 했습니다.
저는 웹 소켓 기본 연결 및 기본적인 CRUD를 JPA로 작성했습니다.
하지만 팀원과의 의사소통 오류로, 팀원분이 예상보다 빠르게 MongoDB 관련 로직을 작성했고, MongoDB가 추가되는 PR을 올렸습니다.
PR을 확인해 보니 다음과 같은 문제가 드러났습니다.
- 기존 ChatService는 JPA에 강하게 의존되어 있었다.
- JPA로 작성한 특정 로직들이 MongoDB로는 작성되어 있지 않아, 프런트와의 연동 시에 MongoDB 로직들을 사용할 수 없었다.
- 새롭게 작성된 MongoChatService는 MongoDB를 강하게 의존하고 있었다. (서비스 내부에서 mongoTemplete을 사용)
코드 구조가 기술에 종속되면서, 프런트와 이미 테스트 중인 기능이 일시적으로 동작하지 않는 문제도 발생했습니다.
다음은 MongoDB관련 로직들이 추가되었을 때의 구조입니다.

저는 충돌을 해결하고 MongoDB 전환 가능성을 열어두기 위해 구조를 변경하기로 했습니다.
해결: 두 DB를 모두 사용할 수 있는 구조로 변경
아래는 문제 해결을 위해 재설계한 구조입니다.

변경 사항은 다음과 같습니다.
- ChatRepository 인터페이스 생성
- ChatService는 해당 인터페이스만 의존
- JPA, Mongo 각각의 구현체를 제공
- ChatService는 어떤 DB를 사용하는지 모름
- 스프링의 DI에 의해 구현체가 결정
- 기술에 독립적인 채팅 관련 도메인(ChatDomain)을 생성
- ChatService에서는 도메인 객체(ChatDomain)를 다룬다.
- 저장 시점에만 엔티티로 변환
- 도메인 객체에는 공통 비즈니스 로직을 담는다.
위의 구조로 개선하고자 구조를 문서화했고, 팀원분에게 구조 개선 시의 장단점을 설명했습니다.
해당 구조로 변경했을 때 예상되는 단점은 다음과 같았습니다.
- 작성해야 할 코드의 양이 많아진다.
- MongoDB로 최종 전환 시 JPA 기반 로직은 불필요해진다.
자세한 설명으로 팀원분의 동의를 얻을 수 있었고, 성공적으로 구조를 변경할 수 있었습니다.
결과
JPA로 작성했던 기존 로직들이 정상적으로 동작하면서 프런트와의 연동을 마무리할 수 있었습니다.
연동을 진행하면서 팀원분은 MongoDB 기반 저장소를 구현했고, 기능 개발 종료 후 JPA->MongoDB로 의존성 주입을 변경하여 성공적으로 마이그레이션을 진행할 수 있었습니다.
'트러블 슈팅' 카테고리의 다른 글
| [MySQL] DISTINCT 사용에 따른 임시 테이블 및 성능 차이 (0) | 2025.09.11 |
|---|---|
| 조회 성능 개선을 위한 @Transactional (3) (1) | 2025.08.25 |
| 조회 성능 개선을 위한 쿼리 최적화 (2) (1) | 2025.08.21 |
| 조회 성능 개선을 위한 쿼리 최적화 (1) (0) | 2025.08.19 |
