- Two-phase Commit은 여러 노드 상에서
원자적 트랜잭션 커밋을 이루기 위한 분산 트랜잭션 프로토콜이다.
- 여러 시스템이 하나의 트랜잭션을 수행할 때, 모든 참여자가 성공적으로 커밋하거나 트랜잭션 전체를 롤백하도록 하여 모든 데이터의 일관성을 유지하는 것이 2PC이다.
필요성
- 데이터베이스는 트랜잭션에서 일부만 데이터베이스에 반영이 되고, 일부는 실패하는 상황을 막기 위해
원자적 트랜잭션을 제공한다.
- 하지만, 단일 노드가 아닌 분산 데이터 베이스에서는 이런 트랜잭션이 어떻게 작동할까?
- 일부 노드에서는 커밋 실패가 발생하나, 일부 노드에서는 성공적으로 커밋된다.
- 그렇다면, 서로 다른 노드 들끼리의 데이터의 불일치가 발생할 수 있는 것이다.
- 그렇기 때문에, 하나의 트랜잭션을 수행할 때, 모든 참여자가 성공적으로 커밋하거나 롤백하게 하여 데이터의 일관성을 유지하는 것이다.
절차

- 2PC는 이름대로 2가지의 phase로 나뉘어 실행이 된다.
- 이때, 새로운 컴포넌트인
코디네이터를 사용하는데, 이는 각 참여자에게 트랜잭션을 준비하게하고 실행 여부를 결정하여 결과를 최종적으로 적용하거나 롤백하게 하는 역할을 한다.
- 아래 과정을 보면 알 수 있지만, 코디네이터를 통해서 2PC는
데이터 일관성과 원자성을 유지한다.
Prepare Phase
코디네이터는 모든 참여자에게 prepare요청을 보낸다.
- 각 참여자는 트랜잭션을 준비하고, 트랜잭션이 성공적으로 커밋될 수 있는 상태인지 확인한다.
- 준비가 가능하면 “Yes”를, 그렇지 않으면 “No”를 반환한다.
Commit phase
- 모든 참여자가 “Yes”라고 응답하면, 각 참여자에게 코디네이터는
commit명령을 보내 트랜잭션을 실행하도록 요청한다.
- 각 참여자는 커밋을 완료한 후 코디네이터에게 보고한다.
- “No”가 하나라도 존재한다면, 코디네이터는 모든 참여자에게
Rollback명령을 보내 트랜잭션을 취소한다.
- 참여자들은 트랜잭션을 롤백하고 코디네이터에게 보고한다.
취약점
- 모든 제 3자 노드를 사용하는 프로토콜 혹은 알고리즘이 갖는 문제점이 존재한다.
- 만약 코디네이터가 다운된다면 어떤 일이 발생할까?
prepare요청을 보내기 전에는 참여자는 트랜잭션을 실행하지 않겠지만, prepare요청을 받고 yes를 응답한 후에 코디네이터가 다운 된다면, 참여자는 abort를 할 수 없다.
- 참여자는 코디네이터의 결정에만 강제되는 특성을 통해 원자성을 유지하기 때문에 어쩔 수 없다.
- 물론 참여자들끼리 서로 상태를 공유함으로써, 문제를 해결할 수 있겠다는 생각이 들지만 해당 부분은 이론적인 2PC 프로토콜에는 고려되어 있지는 않아 보인다.
- 즉, 조정자로 인한 단일 장애 지점이 발생할 수 밖에 없다는 단점이 존재한다.
- 또한, 조정자가 모든 참여자의 응답을 기다리는 과정을 반복하면서 트랜잭션이 진행되기에 대기 시간이 매우 길어질 수 있다.