DB의 Transaction 에 대해 다루다 보면 정말 많이 듣는 용어가 ACID 이다. 트랜잭션 이라는 단어 자체가 매우 모호 하지만, ACID 에서 특히 C 만큼은 정말 모호하다. 그래서 한번 정확히 정리하고 넘어가야겠다는 생각이 들어 더 이상 다시 확인하지 않고, 이 글을 읽는 사람들도 확실히 정리되어 다시 확인하지 않았으면 한다.
Transaction
쇼핑몰에서 카드 결제를 완료하고, 그 이후 어딘가에서 에러가 났다. 그때 결제가 되지 않고, 재고에도 변화가 없도록 DB에 필요한 처리 라는 설명을 듣고 트랜잭션이 무엇인지, 왜 필요한 것인지 한번에 이해가 되었다.
하지만, 트랜잭션 이라는 단어는 매우 모호하다. 일부 비관계형, 관계형에서 트랜잭션을 따른다고 하지만 이 들은 1975년 IBM 의 R시스템에서 소개된 스타일을 따르고 그 개념이 지금까지 사용되는데 조심스러운 추측이지만, 마케팅적인 용어가 아닌가 싶다.
Transaction 을 좀더 엔지니어적으로 표현하자면 "읽기와 쓰기를 하나의 논리적 단위로 묶는 방법" 이라고 정의할 수 있다.
그리고, 묶여진 단위는 commit 되거나 rollback 이라는 기능이 보장되어야 한다.
ACID
트랜잭션이 제공하는 안전성 보장은 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 지속성(Durability) 를 의미하는 ACID 로 알려져 있다.
그러나 실제로 DB 회사 마다 그 정의가 조금씩 다르며, 그래서 무엇을 보장하는지 역시 직접 살펴봐야 한다. 우리에게 중요한 것은 전체적인 흐름보다도 때론 매우 작은 detail 상황 때문이다.
이러한 ACID 표준을 따르지 않는 시스템을 BASE 라고 부르며, 다음의 특징을 따른다
•
기본적으로 가용성을 제공하고(Basically Available)
•
유연한 상태를 가지며(Soft state)
•
최종적 일관성(Eventual consistency)
ACID 보다 더 애매하다.
원자성: Atomicity
일반적으로 원자적 이라 하면, 더 쪼갤 수 없는 뭔가를 의미하며, 대표적으로 Multi Thread 가 원자적인 연산을 실행할 때 다른 thread 에서 절반만 완료된 연산을 관찰할 수 없는, 그래서 실행 전과 후의 상태만 존재하는 경우를 의미한다.
하지만, Transaction 에서 원자성은 이와 연관이 없다(오히려 Isolation 에 가깝다)
ACID 에서 원자성이라 하면, client 가 쓰기 몇 개의 작업을 수행하고자 할 때, 그중 일부만 처리된 후 결함이 발생하여(예를 들어 process 가 죽거나, network 연결이 끊어지거나, 디스크에 문제가 발생하거나, 정합성 조건을 위반하거나 등등) commit 해서 안되는 상황이면 abort (DB는 지금까지 쓴 작업을 무시하거나 취소해야 한다) 하는 작업을 Atomicity 라 한다.
전부 반영되거나, 아무것도 반영되지 않아야 한다.
일관성: Consistency
일관성 이란 단어 역시 굉장히 다양한 범위에서 사용된다. 하지만, ACID 에선 데이터 베이스가 "좋은 상태"에 있어야 한다는 것의 애플리케이션에 특화된 개념을 가리킨다.
일관성이라는 단어가 가지는 의미는 항상 진실이어야 하고, 데이터에 관한 어떤 선언(invariant 불변식)이 있다는 것이다.
예를 들면, 회계 시스템에서 모든 계좌에 걸친 대변과 차변은 항상 맞아떨어져야 한다. 와 같은 예시가 있다.
일관성은 불변식에 의존하고, 불변식 개념은 개념은 application 에서 관리할 책임이다. DB의 책임이라 하기 어렵다. 물론 DB에서 검증하는 불변식 개념도 있다(대표적으로 FK, unique 가 이에 해당한다.) 그러나 application 에서 데이터가 유효한지 아닌지를 정의하고 DB는 데이터를 저장할 뿐이다.
원자성, 격리성, 지속성은 DB의 속성이지만, 일관성은 Application 의 속성이라 봐야 한다. 일관성을 성취하기 위해 원자성, 격리성, 지속성에 의존할 수 있지만 DB 만으로 일관성이 달성되지 않는다.
그래서 ACID 에 C가 속하는건 좀 이상하다
격리성: Isolation
DB를 사용할 때 하나의 컴퓨터로만 DB에 접속하지 않는다(미래의 자신에게 message 를 보내지 않는다) 여러 client가 접속하는데 이때 문제는 동일한 record(document)에 접근하면 동시성 문제(경쟁 조건)에 직면한다.
동시에 counter 를 증가시키는 서로 다른 두 client 사이의 경쟁 조건
예를 들어, 특정 개시물의 조회수를 갱신한다 할때, 42의 조회수를 가졌고, user 두명이 해당 게시물에 접근하면 44로 갱신되어야 한다. 하지만 위 그림처럼 경쟁 조건 때문에 43이 되었다.
ACID 에서 격리성은 동시에 실행되는 transaction 은 서로 격리된다는 것을 의미한다. 하나의 트랜잭션이 다른 트랜잭션을 절대로 방해할 수 없다.
이러한 격리성을 직렬성 으로 표현하기도 한다. 각 트랜잭션이 유일한 트랜잭션인 것 처럼 격리시켜 버리는 것을 의미하는데 각 트랜잭션이 순차적으로 실행됐을 때와 동일한 결과를 보여준다.
대신 성능 손해를 감수해야 한다. snapshot 격리라는 방법도 있다.
지속성: Durability
Data 가 손실될 염려 없이 안전한 저장소를 제공하는 것이다.
지속성은 성공적으로 commit 된 데이터는 H/W 결함이 발생하거나, DB 가 죽더라도 보존되어야 하며
SSD 와 같은 비휘발성 저장소에 기록됐다는 뜻이다.
또한 복제 기능이 있는 DB 에서 지속성은 다른 node 몇 개에 성공적으로 복사가 되었음을 의미하기도 한다.
이 내용으로 부족한 것 같아 트랜잭션에 대한 더 보강된 설명을 추가했다.