배경
마이크로서비스는 각 서비스마다 데이터베이스를 할당하고 이는 다음과 같은 이점을 준다.
- 각 서비스는 자신의 서비스에 적합한 RDBMS를 사용할 수 있다.
- 한 서비스의 장애가 다른 서비스로 전파되지 않는다.
- 독립적인 서비스로 인해 배포와 확장에 유연하다.
하지만 데이터베이스가 독립적이기 때문에 트랜잭션을 보장하는 것이 어렵다는 단점이 있다.
이러한 여러 개의 독립적인 데이터베이스 위에서 하나의 트랜잭션을 수행하기 위해 2PC, SAGA 패턴 등과 같은 분산 트랜잭션 방식이 있다.
2PC
모든 서비스가 트랜잭션을 수행할 준비가 됐을 때만 최종 커밋을 진행하는 방식으로 강한 일관성을 제공한다.
동작 과정

준비 단계, 커밋 단계로 구성되어 있고, 중앙 제어자인 코디네이터가 이를 제어한다.
코디네이터는 여러 서비스들에게 읽기 및 쓰기 작업을 진행하고, 이 과정에서 리소스를 점유한다.
트랜잭션을 수행한 후 커밋을 하려 할 때 아래와 같이 진행한다.
1. 준비 단계
- 코디네이터는 모든 서비스들에게 트랜잭션 준비 요청을 브로드캐스팅한다.
- 각 서비스들은 준비 완료 또는 준비 실패 응답을 코디네이터한테 응답한다.
2. 커밋 단계
- 코디네이터는 모든 서비스의 응답을 받을 때까지 대기한다.
- 모든 서비스가 준비 완료 상태라면 커밋을, 하나라도 실패하면 롤백을 결정한다.
- 결정된 작업을 모든 서비스들에게 브로드캐스팅한다.
- 서비스들은 코디네이터의 요청을 보고 커밋 또는 롤백을 수행한다.
장단점
장점
- 모든 서비스가 성공할 때만 커밋하기 때문에 강한 일관성을 보장한다.
- 상대적으로 이해하기 쉽고, 구현이 단순하며, 관리 비용이 적다.
단점
- 데이터베이스가 분산 트랜잭션을 지원해야 한다.
- 모든 서비스의 응답을 기다려야 하기 때문에 리소스 점유 시간이 길다.
- 코디네이터의 장애가 단일 지점 장애가 된다. 모든 서비스는 코디네이터의 결정을 기다릴 때까지 블로킹 상태가 된다. 만일 2PC 진행 중 코디네이터에 장애가 발생한다면, 모든 서비스는 코디네이터가 복구될 때까지 블로킹 상태가 된다.
발생할 수 있는 장애 상황 및 해결 방법
데이터를 모두 기록한 뒤 코디네이터에 장애가 발생한 경우

- 각 참여자들은 아직 준비 요청을 받지 않은 상태이기 때문에 타임아웃이 발생할 때까지 준비 요청을 기다린 후 트랜잭션을 자동으로 중단한다.
참여자들에게 준비 요청을 보낸 뒤 코디네이터에 장애가 발생한 경우

- 각 참여자들은 커밋이나 롤백 요청을 기다리는 블로킹 상태가 되며, 코디네이터가 복구될 때까지 대기 하게 된다.
- 복구된 코디네이터는 트랜잭션 로그를 확인해서 각 참여자들에게 결정을 다시 요청한다.
모든 참여자에게 커밋 요청을 보낸 뒤, 혹은 보내는 중에 코디네이터에서 장애가 발생한 경우

- 각 참여자들은 이미 커밋 요청을 받았기 때문에 데이터의 변경 사항을 반영한다.
- 코디네이터가 복구된다면, 멱등키와 함께 모든 참여자들에게 커밋 요청을 다시 전송한다.
이를 통해 데이터 불일치를 해결한다.
참여자가 커밋하는 도중에 장애가 발생한 경우

- 참여자는 장애를 복구한 뒤에 트랜잭션 로그를 확인해서 커밋을 마저 진행한다.
참여자가 커밋 요청을 받기 전에 장애가 발생한 경우

- 참여자는 장애를 복구한 뒤에 트랜잭션 로그를 확인해서 준비 상태인 작업에 관해서
코디네이터에게 해당 작업의 결과를 응답 받은 후 해당 응답에 맞게 마저 진행한다.
SAGA 패턴
각 서비스는 독립적인 로컬 트랜잭션을 순차적으로 수행하고, 만일 중간에 실패한다면 그동안 성공했던 트랜잭션을 취소하는 보상 트랜잭션을 역순으로 실행하는 방식이다.
구현 방식
코레오그래피 방식
중앙 제어자 없이 메시지 브로커를 이용해 이벤트 기반으로 다른 로컬 트랜잭션을 트리거하는 방식이다.
장점
- 이벤트의 책임은 각 서비스에 있기 때문에 단일 지점 장애가 없다.
- 트랜잭션 조정을 위한 별도의 서비스가 필요없다.
단점
오케스트레이션 방식
별도의 중앙 제어자가 모든 트랜잭션을 처리하고 이벤트에 따라서 각 서비스들에게 어떤 작업을 수행할지 알려준다.
장점
- 중앙 제어자로 인해 트랜잭션 추적이 쉽다.
- 중앙 제어자가 트랜잭션 및 보상 트랜잭션을 트리거하기 때문에 각 서비스의 로직은 단순해진다.
단점
장단점
장점
- 각 서비스는 자신의 트랜잭션을 처리할 때만 리소스를 점유하므로 2PC 방식보다 락 점유 시간이 짧다.
- 트랜잭션이 작은 단위로 분리되면서 서비스의 가용성이 향상된다.
- 서비스의 독립성이 향상된다.
단점
- 각 트랜잭션에 대한 보상 로직을 설계하고 관리해야 한다.
- 트랜잭션이 진행되는 동안 일시적으로 데이터 불일치가 발생할 수 있다.
- 결과적 일관성을 보장하기 위해 트랜잭션이 발생했음을 다른 서비스들에게 적어도 한번은 알려줘야 하고, 이로 인해 구현의 난이도가 매우 높다.
What is Two Phase Commit in Distributed Transaction?
가상 면접 사례로 배우는 대규모 시스템 설계 기초2
Saga distributed transactions pattern