..

RDBMS 트랜잭션은 왜 필요한가: 논리적 작업 단위와 커밋·롤백

TOC


  1. Overview
  2. 트랜잭션은 왜 필요한가
  3. 하나의 논리적 작업 단위
  4. 예시: 계좌 이체가 중간에 실패한다면?
  5. BEGIN, COMMIT, ROLLBACK
  6. Conclusion

Overview


애플리케이션의 한 가지 기능이 항상 하나의 SQL로 끝나는 것은 아니다.

계좌 이체를 처리하려면 출금 계좌의 잔액을 차감하고, 입금 계좌의 잔액을 증가시키고, 이체 이력도 저장해야 한다. 사용자에게는 한 번의 이체지만 데이터베이스에서는 여러 SQL이 실행된다.

이때 일부 SQL만 성공하면 데이터가 서로 맞지 않는 상태로 남는다. 트랜잭션은 여러 작업을 하나의 단위로 묶어 이런 문제를 막는다.

트랜잭션은 왜 필요한가


아래 두 SQL이 계좌 이체를 처리한다고 가정해 보자.

UPDATE account
SET balance = balance - 10000
WHERE account_id = 1;

UPDATE account
SET balance = balance + 10000
WHERE account_id = 2;

첫 번째 SQL이 성공한 뒤 두 번째 SQL이 실패하면 출금만 처리되고 입금은 처리되지 않는다. 각각의 SQL은 정상적으로 실행됐지만, 계좌 이체라는 전체 기능은 실패한 것이다.

데이터베이스에는 두 SQL이 같은 업무에 속한다는 사실을 알려줄 필요가 있다. 이때 사용하는 것이 트랜잭션이다.

하나의 논리적 작업 단위


트랜잭션은 여러 데이터 변경을 묶은 하나의 논리적 작업 단위다.

계좌 이체를 기준으로 보면 다음 작업이 하나의 트랜잭션에 속할 수 있다.

  1. 출금 계좌의 잔액을 차감한다.
  2. 입금 계좌의 잔액을 증가시킨다.
  3. 이체 이력을 저장한다.

각각은 별도의 SQL이지만 업무 관점에서는 하나의 이체다. 따라서 세 작업은 전부 성공하거나, 하나라도 실패하면 전부 취소되어야 한다.

중요한 점은 데이터베이스가 업무의 범위를 스스로 판단하지 않는다는 것이다. 어떤 작업을 하나로 묶을지는 애플리케이션이 정해야 한다.

예시: 계좌 이체가 중간에 실패한다면?


트랜잭션 없이 다음 순서로 SQL을 실행한다고 가정해 보자.

1. A 계좌에서 10,000원 차감 성공
2. B 계좌에 10,000원 입금 실패
3. 이체 이력 저장 미실행

이 상태에서는 A 계좌의 돈만 사라진다. 실패한 이체인데도 일부 변경이 데이터베이스에 남은 것이다.

반면 세 작업을 하나의 트랜잭션으로 묶으면 중간에 오류가 발생했을 때 A 계좌의 잔액 차감까지 되돌릴 수 있다.

트랜잭션 시작
├─ A 계좌에서 10,000원 차감
├─ B 계좌에 10,000원 입금 시도
└─ 오류 발생 → 앞에서 실행한 변경도 취소

트랜잭션의 목적은 SQL을 단순히 순서대로 실행하는 것이 아니다. 여러 SQL을 하나의 성공 또는 하나의 실패로 다루는 것이다.

BEGIN, COMMIT, ROLLBACK


트랜잭션은 시작한 뒤 실행 결과에 따라 확정하거나 취소한다.

BEGIN;

UPDATE account
SET balance = balance - 10000
WHERE account_id = 1;

UPDATE account
SET balance = balance + 10000
WHERE account_id = 2;

INSERT INTO transfer_history(from_account_id, to_account_id, amount)
VALUES (1, 2, 10000);

COMMIT;
  • BEGIN: 트랜잭션을 시작한다.
  • COMMIT: 트랜잭션 안에서 수행한 변경을 확정한다.
  • ROLLBACK: 트랜잭션 안에서 수행한 변경을 취소한다.

두 번째 UPDATE나 이력 저장에서 오류가 발생하면 COMMIT 대신 ROLLBACK을 실행한다.

ROLLBACK;

그러면 트랜잭션이 시작된 이후의 변경이 취소되어 이체 전 상태로 돌아간다.

Conclusion


트랜잭션은 여러 SQL을 하나의 논리적 작업 단위로 묶는다.

  • 모든 작업이 성공하면 COMMIT으로 변경을 확정한다.
  • 하나라도 실패하면 ROLLBACK으로 변경을 취소한다.
  • 어떤 작업을 하나의 트랜잭션으로 묶을지는 업무 단위를 기준으로 결정한다.

한 줄로 정리하면 다음과 같다.

트랜잭션은 여러 데이터 변경을 하나의 성공 또는 하나의 실패로 처리하기 위한 작업 단위다.