Transaction은 데이터베이스의 상태를 변환시키는 작업의 단위입니다.
데이터베이스의 상태를 변화시킨다는 것은 간단하게 말해서 SQL를 이용해 데이터베이스에 SELECT, INSERT, DELETE, UPDATE 등으로 접근하는 것을 의미합니다.
Transaction은 여러 질의어(SQL)가 포함될 수 있습니다.
예시 1) Velog에 글을 쓸 때 사용자는 게시글을 작성하고 출판하기 버튼을 누릅니다. 그 후에 새로운 글이 포함된 글 목록을 볼 수 있습니다. 이러한 상황을 데이터베이스 작업으로 보면 사용자가 출판하기 버튼을 눌렀을 때 INSERT문을 사용하여 게시글의 데이터를 옮깁니다. 그 후 글 목록에 보일 데이터를 다시 SELECT하여 최신 정보로 유지합니다(ex. 최신 10개의 글만 보이기). 여기서 작업의 단위는 INSERT와 SELECT문을 합친것입니다.
예시 2) A계좌에서 B계좌로 계좌이체를 할 때, 다음과 같은 과정을 거칩니다.
이렇게 게시글을 출판하거나 계좌이체를 하는 등의 하나의 작업단위를 Transaction이라고 합니다. 하나의 Transaction 설계를 잘하는것이 데이터를 다루는 것에 많은 이점이 있습니다.
Transaction은 크게 4가지 특성이 있습니다.
원자성 성질로인해 Transaction 도중 시스템 오류가 발생하면 데이터베이스에 어떤 결과도 반영되지 않습니다.
Commit 연산
Commit 연산은 한 개의 Transaction(작업 단위)에 대한 작업이 성공적으로 끝났고 데이터베이스가 일관성있는 상태에 있을 때 하나의 Transaction이 끝났다라는 것을 알려주는 연산입니다.
Rollback 연산
Rollback 연산은 한 개의 Transaction 처리가 비정상적으로 종료되어 데이터베이스의 원자성이 깨진경우, 해당 Transaction의 일부 연산이 정상적으로 처리되었더라도 모든 연산을 취소(Undo)하는 연산입니다. Rollback시에는 해당 Transaction을 재시작하거나 폐기합니다.
Transaction의 상태는 아래 그림과 같이 나타낼 수 있습니다.
ACID 속성을 구현하는 건 간단한 문제가 아닙니다. Transaction엔 인덱스 업데이트를 비롯한 수많은 연산이 필요하기 때문이죠. 모든 연산이 한번에 실행되면 좋지만 공간부족이나 CPU자원 점유문제등으로 제한이 있습니다. 널리 사용하는 두 가지 방법은 로그(log)방식과 섀도우 패이징(shadow paging) 방식입니다.
로그방식은 DB에 데이터를 업데이트 하기전에 로그에 모든 변경사항을 기록함으로 원자성을 보장합니다. 섀도우 패이징 방식은 변경사항이 DB의 복사본에 저장됩니다. 그리고 새로운 복사본은 Transaction이 commit되면 활성화 됩니다.
금융 시스템같이 오류가 나면 안되는 중요한 작업일수록 Transaction의 설계가 중요한 것 같습니다. Transaction이 포함하는 연산이 많아질수록 시간이 오래걸리고 Rollback의 확률이 증가하고, Transaction이 포함하는 연산이 적어지면 계좌이체에서 돈은 빠지고 상대방 계좌에 금액이 전달이 안되는 등의 오류가 발생할 수 있습니다. 작업마다 Transaction의 설계를 잘 해야 치명적 오류도 방지하고 Commit이 되는 비율도 높일 수 있을 것입니다.
참조 사이트
https://ko.wikipedia.org/wiki/ACID
https://doooyeon.github.io/2018/09/28/transaction.html
https://mommoo.tistory.com/62
https://coding-factory.tistory.com/226
https://d2.naver.com/helloworld/407507