ACID
ACID는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어입니다.
데이터베이스에서 데이터에 대한 하나의 논리적 실행단계를 트랜잭션이라고 합니다. 예를 들어, 은행에서의 계좌이체를 트랜잭션이라고 할 수 있는데 계좌이체 자체의 구현은 내부적으로 여러 단계로 이루어질 수 있지만 전체적으로는 '송신자 계좌의 금액 감소', '수신자 계좌의 금액 증가'가 한 동작으로 이루어져야 하는 것을 의미합니다.
"읽기와 쓰기를 하나의 논리적 단위로 묶는 방법" 이라고 정의할 수 있습니다.
또한, 묶여진 단위는 commit 되거나 rollback 이라는 기능이 보장되어야 합니다.
1️⃣ Atomicity
ACID에서 원자성이라고 하면, client가 쓰기 몇 개의 작업을 수행하고자 할 때, 그 중 일부만 처리된 후 결함이 발생하여(예를 들어 process가 죽거나, network 연결이 끊어지거나, 디스크에 문제가 발생하거나, 정합성 조건을 위반하거나 등등) commit 해서 안되는 상황이면 abort(DB는 지금까지 쓴 작업을 무시하거나 취소해야 한다) 하는 작업을 Atomicty 라고 합니다.
즉, 전부 반영되거나, 아무것도 반영되지 않아야 합니다.
2️⃣ Consistency
일관성은 데이터베이스의 상태가 일관되어야 한다는 성질입니다. 하나의 트랜잭션 이전과 이후 데이터베이스의 상태는 이전과 같이 유효해야 합니다. 다시 말해, 트랜잭션이 일어난 이후의 데이터베이스는 데이터베이스의 제약이나 규칙을 만족해야 한다는 뜻입니다.
예를 들어 '모든 고객은 반드시 이름을 가지고 있어야 한다'는 데이터베이스의 제약이 있다고 가정해봅시다.
다음과 같은 트랜잭션은 Consistency를 위반합니다.
1. 이름 없는 새로운 고객을 추가하는 쿼리
2. 기존 고객의 이름을 삭제하는 쿼리
데이터베이스의 유효한 상태는 다를 수 있지만, 데이터의 상태에 대한 일관성은 변하지 않아야 합니다.
위의 예시는 '이름이 있어야 한다' 라는 제약을 위반합니다.
따라서 예시 트랜잭션이 일어난 이후의 데이터베이스는 일관되지 않은 상태를 가지게 됩니다.
3️⃣ Isolation
격리성은 모든 트랜잭션은 다른 트랜잭션으로부터 독립되어야 한다는 뜻입니다.
실제로 동시에 여러 개의 트랜잭션들이 수행될 때, 각 트랜잭션은 고립(격리)되어 있어 연속으로 실행된 것과 동일한 결과를 나타냅니다.
+ 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미합니다.
은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없습니다.
공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미합니다.
성능적인 이유로 인해 이 특성은 가장 유연성 있는 제약 조건입니다.
4️⃣ Durability
지속성은 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미합니다. 하나의 트랜잭션이 성공적으로 수행되었다면, 해당 트랜잭션에 대한 로그가 남아야합니다.
예를 들어 은행에서 계좌이체를 성공적으로 실행한 뒤에, 해당 데이터베이스에 오류가 발생해 종료되더라도 계좌이체 내역은 기록으로 남아야 합니다.
마찬가지로 계좌이체를 로그로 기록하기 전에 시스템 오류 등에 의해 종료가 된다면, 해당 이체 내역은 실패로 돌아가고 각 계좌들은 계좌이체 이전 상태들로 돌아가게 됩니다.
ACID 구현
최근까지 DB들은 대부분 ACID를 보장하기 위해 락(lock)에 의존했습니다. 이것은 데이터 처리전에 언제나 락이 필요함을 의미합니다. 많은 수의 락을 관리하게 되면 동시작업 수행이 어렵고 성능저하를 초래하게 됩니다. 예를 들어, A 유저가 특정 테이블을 읽고 있다면 B 유저는 A의 트랜잭션이 끝나기를 기다려야 합니다.
락의 대안으로 수정되는 모든 데이터를 별도 복사본으로 관리하는 MVCC(다중 버전 동시성 제어)가 있습니다.
방금 전 언급한 A, B 유저의 예를 들면 A가 트랜잭션을 시작할 때 가지고 있던 복사본을 B에 제공하여 동시에 수행이 가능합니다.
이 방식은 사용자들이 데이터 처리하는 데 있어 많은 유연성을 제공합니다.
네트워크 환경에서 ACID특성을 보장하는 것은 어렵습니다. 연결이 끊길 수도 있고 두 사용자가 동시에 DB의 동일한 부분을 접근할 수도 있습니다.
트랜잭션의 commit 여부를 각 사용자로부터 확인하기 위해 2단계 commit이 분산 트랜잭션에 적용됩니다.
트랜잭션이 병렬 수행되는 경우 많은 주의가 필요합니다. 2단계 락은 완전한 독립성을 위해 사용됩니다.
2단계 commit(2PC, Two-phase commit)는 아래 글을 참고해주세요.
https://kadensungbincho.tistory.com/125
출처
https://ko.wikipedia.org/wiki/ACID
https://blog.yevgnenll.me/posts/what-is-acid-about-transaction
'Database' 카테고리의 다른 글
락이란 무엇일까..? (1) | 2022.12.06 |
---|