DynamoDB가 "NoSQL은 트랜잭션이 없다"는 편견을 깬 것은 2018년 11월이었다. 그 이전까지는 금융 시스템이나 재고 관리처럼 ACID가 필요한 워크로드에 DynamoDB를 쓰려면 애플리케이션 레이어에서 복잡한 분산 락을 직접 구현해야 했다. TransactWriteItems API 출시로 여러 테이블에 걸친 원자적 쓰기가 가능해지면서 그 벽이 사라졌다. 그러나 트랜잭션을 무작정 쓰면 비용이 정확히 2배가 되고, 조건부 쓰기의 멱등성 특성을 모르면 네트워크 재시도가 데이터 중복을 만든다. 이 day에서는 DynamoDB 트랜잭션의 2단계 커밋 내부 동작, 조건부 쓰기로 경쟁 조건을 방지하는 패턴, TTL이 비동기로 삭제하는 이유와 그 함의를 깊이 파고든다.
DynamoDB 트랜잭션은 분산 데이터베이스 이론의 2단계 커밋(2-Phase Commit, 2PC) 프로토콜을 기반으로 구현된다. 2PC는 짐 그레이(Jim Gray)가 1970년대에 형식화한 알고리즘으로, 분산 시스템에서 원자적 커밋을 보장하는 표준 방법이다.
1단계(Prepare): 트랜잭션에 포함된 모든 항목에 잠금을 걸고, 모든 조건을 검사한다. 하나라도 실패하면 전체 롤백. 2단계(Commit): 모든 항목의 조건이 만족됐을 때 실제 변경을 적용하고 잠금 해제.