DB의 소프트웨어나 하드웨어는 언제라도 실패할 수 있음
애플리케이션은 언제라도 죽을 수 있음
네트워크가 끊기면 애플리케이션과 DB의 연결이 끊기거나 DB 노드 사이의 통신이 끊길 수 있음
여러 클라이언트가 동시에 DB를 사용해서 다른 클라이언트가 쓴 내용을 덮어쓸 수 있음
클라이언트가 부분적으로만 갱신되서 비정상적인 데이터를 읽을 수 있음
클라이언트 사이의 경쟁 조건은 예측하지 못한 버그를 유발할 수 있음
위 문제들을 단순화하는 메커니즘의 형태
애플리케이션에서 몇 개의 읽기와 쓰기를 하나의 논리적 단위로 묶는 방법
트랜잭션은 전체가 성공(커밋)하거나 실패(롤백)로 처리
트랜잭션의 장점은 애플리케이션에서 오류 처리를 하기가 훨씬 단순해진다는 점임
트랜잭션을 사용함으로써 애플리케이션은 어느 정도의 잠재적인 오류 시나리오와 동시성 문제를 무시할 수 있음
거의 모든 관계형 데이터베이스와 일부 비관계형 데이터베이스에서 트랜잭션을 지원
NoSQL 데이터베이스는 새로운 데이터 모델, 복제와 파티셔닝 등 관계형 데이터베이스의 개선을 목표로 발전
하지만, 이러한 발전에있어 트랜잭션은 고려되지 않거나, 약한 보장을 의미하는 단어로 축소됨
즉, 높은 성능과 고가용성을 유지하기 위해서는 트랜잭션이 포기되어야 한다는 트레이드오프가 발생
트랜잭션이 제공하는 안정성 보장
원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability)을 의미하는 약어
하지만, 현실의 데이터베이스에서 ACID의 구현은 제각각이며, 실제로 ACID를 준수한다고 했을 때, 어떤 것을 기대할 수 있는지 분명하지 않게 됨
원자성(Atomicity)
일관성(Consistency)
격리성(Isolation)
지속성(Durability)
ACID에서 원자성과 격리성은 클라이언트가 한 트랜잭션 내에서 여러 번의 쓰기를 하면 데이터베이스가 어떻게 해야 하는지를 의미
원자성
격리성
이러한 정의는 한 번에 여러 객체(로우, 문서, 레코드)를 변경할 수 있음을 가정(다중 객체 트랜잭션은 흔히 데이터의 여러 조각이 동기화된 상태로 유지되어야 할 때 필요)
다중 객체 트랜잭션은 어떤 읽기와 쓰기 연산이 동일한 트랜잭션에 속하는지 알아낼 수단이 필요(일반적인 관계형 데이터베이스에서 BEGIN TRANSACTION 문과 COMMIT 문 사이의 모든 것은 같은 트랜잭션에 속하는 것으로 여김)
반면 비관계형 데이터베이스에서는 이런 식으로 연산을 묶는 방법이 없는 경우가 많음
원자성과 격리성은 단일 객체 쓰기에서도 적용됨
보편적으로 원자성은 장애 복구용 로그를 써서 구현되며, 격리성은 각 객체에 잠금을 사용해 동시에 한 스레드만 객체에 접근하도록 구현됨
하지만 이러한 단일 객체 연산은 엄밀히 말하자면 ACID로 간주되지 않음
트랜잭션은 보통 다중 객체에 대한 다중 연산을 하나의 실행단위로 묶는 메커니즘을 의미
많은 분산 데이터스토어는 다중 객체 트랜잭션 지원을 포기(불가능 한 것은 아님, 9장에서 분산 트랜잭션에 대해 다룰 예정)
여러 파티션에 걸쳐서 구현하기가 어렵고, 매우 높은 가용성과 성능이 필요한 곳에서는 방해가 되는 시나리오도 있기 때문
key-value 데이터 모델과 단일 객체 연산만을 사용해서 애플리케이션을 구현할 수도 있지만, 많은 경우에 있어서 여러 객체에 실행되는 쓰기 작업은 코디네이션돼야 함
관계형 모델의 외래키와 같이 그래프형 모델의 정점은 간선이 존재. 즉, 서로 참조되는 여러 레코드를 삽입할 때 참조 키를 올바른 최신 정보를 반영해야 함
조인 기능이 없는 문서 데이터 모델은 비정규화를 장려하기도 함. 이처럼 비정규화된 정보를 갱신할 때는 한 번에 여러 문서를 갱신해야 함을 의미
보조 색인이 있는 데이터베이스는 값을 변경할 때마다 색인도 갱신되어야 함
위 예시는 모두 트랜잭션이 없더라도 구현할 수는 있음. 하지만, 오류처리가 훨씬 복잡해지고 동시성 문제도 발생될 수 있음
트랜잭션의 핵심기능은 오류가 생기면 어보트되고 안전하게 재시도할 수 있다는 것. ACID의 철학이며, 데이터베이스는 원자성, 격리성, 지속성 보장을 위반할 위험이 있으면 트랜잭션을 완전히 폐기함으로서 이를 달성함
하지만, 어보트된 트랜잭션을 재시도한다는 것이 완벽한 것은 아님
트랜잭션이 성공했지만, 성공을 알리는 도중 네트워크가 끊기게 되면 클라이언트는 재시도할 것이고 이는 트랜잭션이 두 번 실행될 수 있음을 의미함. 애플리케이션에 추가적인 중복 제거 메커니즘이 필요한 이유
오류가 과부하때문이라면 재시도는 문제를 개선하는 것이 아니라 악화시킬 수 있음
오류가 일시적인 오류가 아닌 영구적인 오류라면, 재시도는 아무런 의미가 없음