[DB] (6) 트랜잭션과 TCL : 안정적인 데이터 관리를 위한 제어 방법

이영교·2024년 8월 31일
0

DB

목록 보기
6/11
post-thumbnail

트랜잭션 필요성

트랜잭션(Transaction)의 사전적인 의미는 거래를 뜻한다. 이것은 하나의 작업을 위해 더 이상 분할될 수 없는 논리적인 작업 단위를 의미한다. 즉, 한꺼번에 수행되어야 할 일련의 연산모음을 뜻한다.

왜 우리는 트랜잭션이란 개념을 알아야 하는 것일까? 다음과 같은 상황을 상상해보자.

밥을 같이 먹은 대학생 A, B는 더치페이를 하기 위해 미리 결제한 A에게 B가 돈을 송금하는 상황이다. B가 A에게 돈을 송금함으로써, B의 계좌에서 잔고가 차감되었는데, 중간에 예기치 못한 오류로 인해 A의 계좌에는 입금이 되지 않은 상황이 발생했다.

이와 같이 트랜잭션이 가장 많이 활용되는 상황으로, 계좌이체를 예시로 들 수 있다. 계좌이체는 입금과 출금 두 가지 과정으로 이루어진다. 만약 이처럼 B는 송금을 성공했지만, A의 계좌에서는 입금이 실패했다면 돈이 사라지는 결과를 볼 수 있다. 이런 이유로 두 과정이 원자적(Atomic)처럼 수행되도록 보장할 필요가 있다. 즉, 입금과 출금의 작업을 하나의 단위로 묶어, 둘 다 성공하거나 실패하도록 만들 수 있다. 이를 가능하게 하는 것이 트랜잭션의 개념이다.

트랜잭션은 이외에도 많은 상황에서 활용된다. 데이터 처리의 안정성을 확보하기 위한 필수적인 매커니즘으로, 특히 금융 거래와 같은 중요한 데이터를 처리할 때 이 개념은 더욱 중요한 역할을 한다.

이번 글에서는 트랜잭션의 개념과 함께 이를 제어하는 TCL(Transaction Control Language)를 이해해보고자 한다.

트랜잭션 특징

트랜잭션은 수행되는 일련의 작업 집합으로, 하나의 논리적 단위를 형성한다. (All or Nothing) 하나의 트랜잭션은 한 개 이상의 SQL 쿼리로 구성될 수 있으며, 이 쿼리들은 완전히 처리되거나 아예 한 개도 처리되지 않아야 한다. 중요한 점은 트랜잭션이 성공적으로 완료되면 그 결과가 영구적으로 데이터베이스에 반영되고, 실패할 경우에는 데이터베이스가 원래 상태로 돌아가야 한다.

트랜잭션은 다음과 같이 안전성을 보장하기 위해 네 가지 특성(ACID)을 가진다.

  1. 원자성(Atomicity)
    트랜잭션은 더 이상 분해가 불가능한 업무의 최소 단위를 의미한다. 트랜잭션에서 정의된 연산들은 모두 성공적으로 실행되거나 전혀 실행되지 않아야 한다.
  2. 일관성(Consistency)
    트랜잭션이 실행되기 전과 후의 데이터베이스 내용에 잘못이 있으면 안 된다. 트랜잭션 실행의 결과로 데이터베이스의 상태가 모순되지 않도록 실행되어야 한다.
  3. 격리성(Isolation)
    실행 중인 트랜잭션의 중간 결과에 다른 트랜잭션의 접근이 불가능해야 한다. 트랜잭션 간의 간섭이 없어야 한다.
  4. 지속성(Durability)
    트랜잭션이 성공적으로 수행되면, 그 트랜잭션이 갱신한 데이터베이스의 내용은 영구적으로 저장되어야 한다. 시스템이 오류가 발생하더라도 데이터는 보존되어야 한다.

트랜잭션 상태

트랜잭션은 연산과정의 단계를 나타내면 아래와 같이 볼 수 있다.

image

  1. 활성(Active)
    트랜잭션이 정상적으로 실행 중인 상태를 의미한다.
  2. 작업 성공 시
    1. 부분 완료(Partially Committed)
      트랜잭션의 마지막까지 실행되었지만, Commit 연산이 실행되기 직전의 상태
    2. 완료(Committed)
      트랜잭션이 성공되어 Commit 연산을 실행한 이후의 상태, 데이터베이스에 영구적으로 저장. 하나의 트랜잭션 과정이 종료되었다는 것을 의미
  3. 작업 실패시
    1. 실패(Failed)
      트랜잭션 실행에 오류가 발생하여 중단된 상태
    2. 철회(Aborted)
      트랜잭션이 비정상적으로 종료되어 Rollback 연산을 수행한 상태

트랜잭션 격리 수준과 현상

트랜잭션은 독립적으로 처리되어야 하지만, 여러 트랜잭션이 동시에 실행될 때, 서로의 작업에 영향을 미칠 수 있다. 이러한 영향을 최소화하고 데이터의 일관성을 보장하기 위해, 트랜잭션 격리 수준(Isolation Level)이 필요하다. 격리 수준은 다른 트랜잭션의 중간 작업 결과를 얼마나 볼 수 있는지를 결정하는 기준이다.

트랜잭션이 허용하는 격리 수준에 따라 아래와 같이 네 가지로 구분할 수 있다.

  1. READ UNCOMMITTED (가장 낮은 수준)
    트랜잭션에서 처리 중인 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다. 데이터의 일관성이 보장되지 않는다.
  2. READ COMMITTED (일반적으로 가장 많이 사용)
    트랜잭션이 커밋한 변경 사항만을 읽을 수 있다.
  3. REPEATABLE READ
    트랜잭션이 시작된 시점 이후 완료되기 전까지는 Shared-Lock을 적용하여, 다른 트랜잭션은 커밋한 변경 사항을 읽을 수 없다. 동일한 트랜잭션 내에서 같은 데이터를 여러 번 읽더라도 항상 동일한 결과를 보장한다.
  4. SERIALIZABLE (가장 높은 수준)
    Shared-Lock이 범위(Range) 단위로 적용되어 모든 트랜잭션이 순차적으로 실행되는 것처럼 만든다. 트랜잭션 간의 상호작용을 완전히 차단하여 일관성을 최대한 보장한다. 트랜잭션이 완료된 이후 Shared-Lock을 해제한다.

이와 같은 격리 수준을 선택할 때는 시스템의 요구 사항과 성능 사이에서 균형을 고려해야 한다. 예를 들어, 금융 시스템과 같이 높은 일관성이 요구되는 경우, SERIALIZABLE 과 같이 높은 격리 수준을 선택할 수 있지만 그로 인한 성능 저하를 감수해야 한다. 반면에, 일관성보다 성능이 중요한 경우, READ COMMITTED와 같은 낮은 격리 수준이 적합할 수 있다.

이번에는 격리 수준에 따라 발생할 수 있는 현상에 대해 이해해보자.

  1. Dirty Read
    데이터 캐시에는 변경이 되었지만, 디스크에는 변경되기 전에 데이터를 읽어 일관성을 잃는 현상이다.
  2. Non-Repeatable Read
    같은 데이터를 조회할 때, 트랜잭션 낸 다른 시점에 읽은 하나의 데이터 값이 다른 현상이다.
  3. Phantom Read
    트랜잭션 수행 중에 조회한 결과 집합에 새로운 행이 추가되어 새로운 데이터를 읽게 되거나, 존재하던 데이터가 사라지는 현상이다. 동일한 조건으로 읽은 데이터의 개수가 달라지는 현상을 의미한다.
구분Dirty ReadNon-RepeatablePhantom Read
Read Uncommitted가능가능가능
Read Committed불가능가능가능
Repeatable Read불가능불가능가능
Serializable Read불가능불가능불가능

트랜잭션 제어 언어(TCL)

트랜잭션을 제어하고 관리하기 위해 사용되는 SQL이다. 명령어는 주로 트랜잭션의 시작, 커밋, 롤백 등의 작업을 수행한다. 주요 TCL 명령어는 크게 세 가지(COMMIT, ROLLBACK, SAVEPOINT)가 존재한다.

COMMIT

하나의 트랜잭션을 정상적으로 완료하고 그 결과를 데이터베이스에 영구적으로 저장한다.

INSERT INTO EMP
VALUES (102, '홍길동');

COMMIT;

ROLLBACK

트랜잭션 중 실패하거나 오류가 발생한 경우, 이루어진 모든 변경 사항을 취소하고 데이터베이스를 트랜잭션 시작 전의 상태로 되돌린다.

UPDATE EMP
	SET EMP_NAME = '이순신'
WHERE EMP_NAME = '홍길동';

ROLLBACK;

SAVEPOINT

트랜잭션 내에서 특정 시점(SAVEPOINT)를 설정하여, 트랜잭션이 실패할 경우 이 지점으로 롤백할 수 있다. 트랜잭션 내에 여러 개의 SAVEPOINT를 지정할 수 있고, 일부만 롤백할 수 있도록 한다.

SAVEPOINT SP1;
INSERT INTO EMP VALUES(102, '홍길동');

SAVEPOINT SP2;
INSERT INTO EMP VALUES(103, '이순신;);

ROLLBACK TO SP2;

결론

트랜잭션은 데이터베이스의 무결성과 일관성을 유지하는 데 필수적인 도구라고 생각된다. 이 개념이 존재하지 않는다면, 금융 시스템에서는 금전적인 문제와 직결되는 크나큰 문제가 발생할 수 있다. 따라서, 데이터를 다루는 시스템의 경우 안정성을 유지하기 위해 트랜잭션을 적절하게 사용하는 것이 좋을 것 같다.

앞으로 트랜잭션에 대한 개념을 더 깊게 살펴보도록 노력해야겠다.

profile
글쓰기 연습하는 사람입니다.

0개의 댓글