본문 바로가기
DBMS

[DBMS] RDBMS에서 트랜잭션의 ACID 규칙

by 도전하는 린치핀 2024. 3. 13.

 

1. RDBMS에서 트랜잭션이란 무엇인가?

  • 데이터베이스에서 데이터에 대한 하나의 논리적인 작업 단위를 의미한다.
  • 논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나누어질 수 없도록 만든 것
  • 트랜잭션 내 SQL문들은 모두 성공하는 경우 commit되고, 하나라도 실패하는 경우에는 전체가 rollback된다.
  • 트랜잭션 내 SQL문 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.

트랜잭션의 하나의 예로 은행 어플에서 계좌이체를 한다고 가정해보자.

계좌이체라는 하나의 작업을 위해서 은행 어플에서는 내부적으로 여러 단계의 업무를 거쳐야 할 수 있다.

간단하게 업무를 요약하면 [송신자 계좌 금액 감소], [수신자 계좌 금액 증가]이 있을 것이다.

이렇게  단계에 대한 데이터를 처리하는 논리적 행위 트랜잭션이라고 합니다.

그러면 사용자가 원한 "계좌이체"라는 업무가 완료되려면 [송신자 계좌 금액 감소] [수신자 계좌 금액 증가] 어느 하나만 이루어져서는 안된다. 반드시 두개의 논리적인 행위(트랜잭션)이 완료되어야 "계좌이체"가 완료되었다고 할 수 있다.

만약 사용자가 "계좌이체"를 원했는데 [송신자 계좌 금액 감소] 업무만 완료되었다고 한다면 이것은 "계좌이체"가 아니라 보이스피싱,,,에 가까운 업무가 되어버리는 것이다.

 

따라서 보이스피싱이 되지 않기 위해 트랜잭션에서는 ACID라는 규칙을 반드시 지켜야 한다.

 

2. 트랜잭션의 ACID는 무엇인가?

 

위에서 말했다시피 트랜잭션의 ACID 규칙은 트랜잭션이 지녀야하는 속성과도 같은 것이다.

모든 트랜잭션은 ACID 규칙을 모두 보장해 안전한 데이터베이스 내 트랜잭션이 이루어질 수 있다.

 

ACID 각각 Atomicity(원자성), Consistency(일관성), Isolation(고립성), Durability(지속성)의 앞글자만 가져온 것이다.

2-1.  Atomicity (원자성)

  • ALL OR NOTHING
  • 트랜잭션은 모두 실행하거나 모두 실행하지 않음 두 가지 상태만

트랜잭션은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 내부의 SQL문들이 모두 성공하고나, 중간에 어떤 하나의 SQL문이라도 실패하면, 지금까지 작업을 모두 취소해 이전 상태로 롤백해야 한다. 

즉, 일부만 성공하는 상태는 존재해서는 안된다. 

 

성공 시 커밋했을 때 DB에 영구적으로 저장하는 것과 실패 시 롤백했을 때 이전 상태로 되돌리는 것은 DBMS가 담당하는 부분이다.

개발자는 언제 커밋하고 언제 롤백할 지에 대한 기준을 세우고 코드를 작성해야 한다

 

즉, 위에서 예로 들었던 은행업무에서 "계좌이체"라는 업무가 완료되기 위해서는 [송신자 계좌 금액 감소], [수신자 계좌 금액 증가] 업무가 완료되어야 한다는 것이다.

 

2-2. Consistency (일관성)

  • 트랜잭션 이전과 이후에 데이터베이스는 항상 consistent한 상태여야 한다는 규칙이다.
  • 트랜잭션은 DB 상태를 consistent 상태에서 또 다른 consistent 상태로 가야 한다. 

트랜잭션이 실행을 성공적으로 완료되었을 , 이전의 상태와 결과의 상태가 항상 안정된 상태로 있어야 한다는 것이다.

은행 어플에서 은행 업무를 예를 들어 내 계좌에 잔고가 10,000원이 있고 송금을 받을 사람의 계좌 잔고가 20,000원일 내가 5,000원을 계좌이체 업무를 완료해도, 내 계좌와 송금 받을 사람의 계좌의 합은 30000원으로 동일하다는 뜻이다.

 

만약에, constraints, trigger 등을 통해서 DB에 정의된 규칙을 트랜잭션이 위반했다면 롤백해야 한다.

트랜잭션이 DB에 정의된 규칙을 위반했는지는 DBMS가 커밋 전에 확인하고 알려준다.

그렇다고 DBMS를 맹신하기보다는, 애플리케이션 관점에서 트랜잭션이 consistent하게 동작하는지는 개발자도 챙겨야 한다. 

 

2-3. Isolation (고립성)

  • 여러 트랜잭션이 동시에 실행될 때에도, 혼자 실행되는 것처럼 동작하게 만들어야 한다.
  • 트랜잭션을 수행하는 동안 다른 트랜잭션이의 연산 작업이 끼어들지 못하게 한다는 뜻이다.
  • 즉, 동시에 실행되는 여러 트랜잭션은 서로 영향을 주지 않고 독립적으로 실행되는 것처럼 보여야 한다.
  • DBMS는 여러 종류의 Isolation level을 제공하고, 개발자는 이중에서 어떤 레벨로 트랜잭션을 동작시킬지 설정할 수 있다. 
  • concurrency control의 목표는 isolation이다. 

Isolation level 같은 경우에는 4개의 단계가 있는데 빠르고 효율적인 트랜잭션의 처리를 위해 각 트랜잭션이 어느정도로 고립되어 있는지 정의한 것이라고 생각할 수 있다.

1단계는 트랜잭션간의 격리가 거의 이루어져 있지 않은 상태부터 4단계는 완전한 격리가 이루어진 직렬화가 있다.

Isolation level은 추후 새로운 포스팅으로 다뤄보자.

 

2-4. Durability (영속성)

  • 성공적으로 수행된 트랜잭션의 결과는 데이터베이스에 영구적으로 저장되어야 한다. 
  • '영구적 저장' == '비휘발성 메모리(HDD, SSD 등)에 저장'
  • 추후에 데이터베이스 전원이 꺼진다던가 뿌서진다던가 등등 문제가 생겨도 커밋된 결과는 계속 데이터베이스에 남아있어야 한다.
  • 트랜젝션 조작을 하드 디스크에 로그로 기록하고 시스템에 이상이 발생하면 그 로그를 사용해 이상 발생 전까지 복원하는 것으로 지속성을 실현하고 있다.