안녕하세요 대덕소프트웨어마이스터고등학교에 재학중인 김도경입니다.
오늘은 Entry (입학전형서비스)를 개발하며 분산 트랜잭션을 해결했던 경험을 공유하려고 합니다
분산 트랜잭션이 왜 문제인가요?

a, b, c 서버가 있을 때
- a 서버에서 데이터를 변경하면 b 서버에도 a 서버에서 변경한 x의 값을 반영해야 합니다.
여기까지는 문제가 없습니다.
b 서버가 장애가 발생한다면?
- A 서버에서 데이터 x의 값을 변경했지만, B 서버에서 장애가 발생하여 A 서버에서 변경한 값을 반영하지 못한다고 가정해 봅시다.
- 이 경우, 분산 환경에서 트랜잭션의 원자성(Atomicity)과 일관성(Consistency)을 지키기 어려워집니다.
원자성 보장 어려움
- B 서버에서 데이터 변경이 이루어지지 않는다면, A 서버는 변경 내용을 롤백하여 장애 발생 전 상태로 되돌려야 합니다.
- 그러나 A 서버와 B 서버는 독립적인 트랜잭션으로 처리되므로, 하나의 트랜잭션처럼 동작하도록 보장하기가 어렵습니다.
일관성 깨짐
- A 서버에서 데이터 변경이 완료되었지만, B 서버에서 반영되지 않는다면 시스템의 전체 상태가 불일치하게 됩니다.
- 즉, A와 B 서버의 데이터 불일치로 인해 시스템의 일관성이 깨집니다.
이제 제 경험을 통해 말하려고 합니다
Entry 프로젝트에서의 문제
A 서버(application)와 S 서버(Status) 간의 분산 트랜잭션 문제를 설명합니다.
- A 서버에서 원서를 최종제출 이벤트를 발생시키면 Kafka를 통해 S 서버에
ReceiptCode가 똑같은 데이터의 status를 최종제출로 변경시켜야 정상적인 흐름입니다.
- A 서버에서 원서 최종 제출 변경 이벤트를 발생시키면 S 서버의 데이터가 변경되지 않아 일관성 문제가 발생.
Kafka를 사용해 해결할 수 있는거 아닌가요?
- Kafka는 이벤트를 디스크에 저장하여 비동기적으로 통신하는 방법을 제공합니다.
- 그러나 S 서버가 언제 복구될지 알 수 없고, Kafka를 통해 이벤트가 성공적으로 전달되더라도 S 서버 내부에서 처리 로직이 문제가 있을 수 있습니다.
- 따라서 Kafka만으로는 분산 트랜잭션 문제를 해결할 수 없습니다.
그렇다면 어떻게 해결했나요?
SAGA, 2PC, TCC 등 다양한 패턴 중 TCC(Try-Confirm/Cancel) 패턴을 사용하여 원자성과 일관성 문제를 해결했습니다.
TCC 패턴이란?
- Try: 트랜잭션을 시도하는 단계입니다.
- Confirm: 성공적으로 완료되었음을 확정하는 단계입니다.
- Cancel: 실패할 경우 롤백을 수행하는 단계입니다.
TCC 패턴의 장점
- 높은 일관성: 데이터의 정확성을 보장할 수 있어 중요한 트랜잭션에 적합합니다.
- 명확한 보상 로직: Cancel 단계에서 데이터 롤백이 가능하여 오류 발생 시 쉽게 복구합니다.
- 변경 가능성: 다른 패턴에 비해 유연하게 비즈니스 로직을 변경할 수 있습니다.
TCC 패턴의 단점
- 복잡성 증가: 트랜잭션을 세 단계로 나누어 처리하므로 설계 및 구현이 복잡해지고 예외 상황을 고려한 로직이 필요합니다.
- 오버헤드 문제: 각 단계에서 확인 및 취소 작업을 거치므로 오버헤드가 발생할 수 있으며, 트랜잭션이 많아지면 성능 저하가 발생할 수 있습니다.
TCC 패턴을 활용한 구현 방법

1. Try: createScoreUseCase를 호출하여 Kafka 이벤트를 생성합니다.
2. Confirm: 예외가 발생하지 않으면 createScoreUseCase가 정상적으로 실행합니다.
3. Cancel: 예외가 발생하고 재시도까지 실패할 경우, recover 함수를 실행하여 복구 작업을 처리합니다.
사진 출처
https://thebook.io/007035/0210/