
Microservice Architecture에서는 각 마이크로 서비스가 독립적인 데이터베이스를 가진다. 트랜잭션이 발생하면 마이크로 서비스들이 서로 통신하며 여러 데이터베이스에 트랜잭션이 발생하는데, 이렇게 분산 환경에서 여러 시스템에 걸쳐있는 트랜잭션을 분산 트랜잭션이라고 한다. 분산 트랜잭션 또한 일반적인 트랜잭션처럼 ACID 속성을 가져야한다. 분산 트랜잭션을 관리하는 방법에 대해 알아보자.
Two-phase Commit, 줄여서 2PC는 분산 트랜잭션을 관리하기 위한 알고리즘으로, 분산 트랜잭션이 모두 commit되거나 모두 rollback되도록 하여 Atomicity(원자성)를 보장한다.
분산 트랜잭션에 참여하는 데이터베이스 노드를 참여자(Participant)라고 부르고, 분산 트랜잭션을 제어할 코디네이터(Coordinator)가 존재한다.
2PC는 두 단계로 이루어진다.

prepare 메세지를 보낸다.prepare 메세지를 받으면 트랜잭션을 실행하고 코디네이터에게 성공하면 yes, 실패하면 no 메세지를 보낸다.yes 응답을 받으면 모든 참여자에게 commit 메세지를 보낸다.commit 메세지를 받으면 트랜잭션을 커밋하고 코디네이터에게 ack를 보낸다.no 메세지를 받으면 모든 참여자에게 rollback 메세지를 보낸다.rollback 메세지를 받으면 트랜잭션을 롤백하고 코디네이터에게 ack를 보낸다.Redo log와 Undo log
데이터베이스에서 트랜잭션 관리와 복구를 위해 사용되는 로그. 트랜잭션이 커밋되면 로그는 디스크의 로그 파일에 영구적으로 저장되어 데이터베이스에 장애가 발생하더라도 Durability를 보장할 수 있음.
- Redo log : 트랜잭션에서 데이터를 변경할 때, 데이터의 변경사항을 기록하는 로그. 데이터베이스에 장애가 발생한 경우에 커밋된 트랜잭션을 복구하는데 사용됨
- Undo log : 트랜잭션에서 데이터를 변경하기 전, 데이터의 원래 상태를 기록하는 로그. 트랜잭션을 롤백할 때 사용됨.
트랜잭션이 Commit 되는 과정
- 트랜잭션 중 데이터 변경 : 트랜잭션 실행 중 데이터가 변경되면, 변경된 데이터는 메모리의 Buffer Cache에 반영되고, Redo log는 메모리의 Redo log Buffer에 반영된다.
- 커밋 : 트랜잭션이 커밋되면 Redo log Buffer에 있던 Redo log는 디스크에 기록된다. (다른 조건을 충족하면 트랜잭션 중간에도 기록될 수 있다. 이 시점을 Checkpoint라 한다.)
- 변경된 데이터 기록 : Buffer Cache에 존재하는 변경된 데이터는 커밋 시점이 아니라 나중에 디스크에 기록된다.
- Redo log로 트랜잭션 복구 : Buffer Cache에 존재하는 변경된 데이터가 디스크에 반영되지 못하고 데이터베이스에 장애가 생기면, Redo log를 이용하여 트랜잭션을 복구한다.
※ 트랜잭션이 커밋되기 전에 장애가 생겨 Buffer Cache와 Redo log Buffer가 모두 사라질 경우? 커밋되지 않은 트랜잭션은 복구하지 않는다. 커밋된 트랜잭션에 한해서만 ACID를 보장한다.
트랜잭션이 Rollback 되는 과정
- 트랜잭션 중 데이터 변경 : 트랜잭션 실행 중 데이터가 변경되면, 변경되기 전의 데이터는 Undo log에 기록되어 메모리의 Undo log Buffer에 반영되고, 변경된 데이터는 메모리의 Buffer Cache에 반영된다.
- 디스크에 Undo log 기록 : Checkpoint에 Undo log Buffer에 있던 Undo log는 디스크에 기록된다.
- 롤백 : 트랜잭션이 롤백되면 Undo log Buffer에 있던 Undo log를 사용하여 Buffer Cache에서 변경된 데이터를 원래 상태로 되돌린다. 또한 디스크에 이미 반영된 변경된 데이터도 Undo log를 사용하여 되돌린다.
XA 프로토콜은 분산 트랜잭션의 처리를 위해 X/Open에서 정의한 표준이다. XA 프로토콜은 Two-phase Commit 알고리즘을 이용하여 분산 트랜잭션을 처리한다.