SQL: TCL

김기현·2025년 6월 11일

Database

목록 보기
6/24

TCL(Transaction Control Language)은 데이터베이스에서 트랜잭션(논리적인 작업 단위)를 제어하는데 사용되는 SQL 명령어들이다. 이를 통해 데이터의 일관성과 무결성을 보장할 수 있다.


트랜잭션

트랜잭션은 하나의 작업 단위로 묶인 여러 SQL 문장들을 말한다. 예를 들어 은행 계좌 이체는 다음 두 가지 작업이 동시에 이루어져야 한다.

  1. A 계좌에서 인출
  2. C 계좌로 입금

이 두 작업 중 하나라도 실패하면 전체 작업이 취소되어야 한다. 이처럼 모든 작업이 성공하거나, 아니면 모두 실패해야 하는 것이 트랜잭션이다.

트랜잭션의 4가지 특성

TCL은 다음 ACID 원칙을 만족시키기 위해서 사용된다.

  • Atomicity(원자성): 전부 실행되거나, 전부 취소된다.
  • Consistency(일관성): 트랜잭션 수행 후 데이터 무결성이 유지된다.
  • Isolation(격리성): 동시에 실행되는 트랜잭션 간 간섭 방지.
  • Durability(지속성): COMMIT된 결과는 영구적으로 유지된다.

TCL

주요 명령어

명령어설명
COMMIT트랜잭션의 모든 변경 사항을 영구 저장
ROLLBACK트랜잭션 내에서 발생한 변경 사항을 모두 취소
SAVEPOINT트랜잭션 내에서 롤백 가능한 중간 지점 설정
RELEASE SAVEPOINT설정한 저장 지점 제거
SET TRANSACTION트랜잭션의 속성(격리 수준 등)을 설정

COMMIT

변경사항을 확정하고 DB에 영구 반영한다.

BEGIN;

UPDATE accounts
SET balance = balance - 100
WHERE id = 1;

UPDATE accounts
SET balance = balance + 100
WHERE id = 2;

COMMIT;

UPDATE가 모두 성공했을 때 COMMIT으로 반영한다.

ROLLBACK

트랜잭션 중 문제가 생기면 되돌린다.

BEGIN;

UPDATE accounts
SET balance = balance - 100
WHERE id = 1;

ROLLBACK;

위 업데이트는 취소되고, DB는 원래 상태로 복구된다.

SAVEPOINT

트랜잭션 중간에 되롤릴 지점을 지정할 수 있다.

BEGIN;

UPDATE accounts
SET balance = balance - 100
WHERE id = 1;

SAVEPOINT sp1; -- 세이브포인드

UPDATE accounts
SET balance = balance + 100
WHERE id = 2;

ROLLBACK TO sp1;
COMMIT; -- 커밋을 실행하면 세이브포인트는 자동으로 삭제된다.

두 번째 UPDATE만 되돌리고, 첫 번째 UPDATE는 유지하고 COMMIT할 수 있다.

  • 세이브포인트는 트랜잭션 내에서만 유효하기 때문에 COMMIT 또는 ROLLBACK되면 세이브포인트는 소멸한다.

RELEASE SAVEPOINT

더 이상 필요 없는 저장 지점을 제거한다.

RELEASE SAVEPOINT sp1;
  • 세이브포인트는 한 트랜잭션 내에서만 살아있는데, 트랜잭션 중간에 세이브포인트를 명시적으로 제거하고 싶을 때 사용한다.
    • 필요할 때: 트랜잭션 진행 중 이미 필요 없다고 판단되면 자원 정리를 위해 사용한다.
    • 필요하지 않을 때: 트랜잭션이 COMMIT 또는 ROLLBACK 되었을 때.
BEGIN;

SAVEPOINT sp1;

-- 다른 쿼리들

-- sp1 더 이상 필요 없으면 제거
RELEASE SAVEPOINT sp1;

COMMIT; -- 어차피 이 시점에 모든 세이브포인트는 사라짐

대규모 트랜잭션에서 RELEASE SAVEPOINT를 사용하는 이유

리소스 관리와 성능 최적화 때문이다. 세이브포인트가 많아지면 아래와 같은 문제가 생긴다.

  1. 메모리 사용량 증가: 각 세이브포인트는 내부적으로 트랜잭션 상태를 저장해야 하므로, DB는 이 상태를 메모리 등에 유지한다.
  2. 트랜잭션 성능 저하 가능성: 세이브포인트가 많으면, ROLLBACK TO시에 어떤 지점으로 돌아가야 할지 DB가 더 많은 상태 정보를 추적해야 하므로 복구나 트랜잭션 실행 성능에 영향을 줄 수
    있다
    .
  3. DBMS에 따라 내부 제한: 일부 DBMS(ProstgreSQL 등)은 세이브포인트 개수에 제한이 있거나, 너무 많으면 경고 또는 성능 저하가 발생할 수 있다.

따라서 RELEASE SAVEPOINT를 사용하는 이유는 다음과 같다.

목적설명
불필요한 세이브포인트 제거더 이상 사용하지 않을 세이브포인트를 명시적으로 제거해 메모리 절약
성능 최적화트랜잭션 중간에 세이브포인트 수를 줄여 복구 시 오버헤드 감소
리소스 관리장시간 실행되는 트랜잭션에서 불필요한 상태 유지 방지

SET TRANSACTION

트랜잭션의 격리 수준을 설정한다.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;

-- 다른 쿼리들

COMMIT;

SET TRANSACTION는 동시성 제어 및 데이터 일관성 문제 방지를 위해 사용한다

격리 수준은 동시에 여러 트랜잭션이 실행될 때, 서로 간섭하지 않도록 하는 정도를 말한다. ANSI SQL에서는 다음과 같은 4가지 격리 수준이 정의되어있다.

격리 수준허용되는 현상설명
READ UNCOMMITED더티 리드 가능다른 트랜잭션의 미롼료 데이터를 읽을 수 있다
READ COMMITED더티 리드 방지커밋된 데이터만 읽는다
REPEATABLE READ터티 리드, 논리적 오류 방지읽은 행은 트랜잭션 종료시까지 고정한다
SERIALIZABLEX트랜잭션을 순차적으로 실행한 것처럼 보이게 한다

다음은 각 상황 별로 예시를 든 SQL이다.

-- 데이터 정합성이 최우선일 때
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
-- 예금 인출 + 입금
COMMIT;

-- 성능이 중요하고, 최신 데이터만 보고 싶을 때
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 트랜잭션이 읽기 전용임을 명시하고 싶을 때
SET TRANSACTION READ ONLY;
BEGIN;
SELECT *
FROM board;
COMMIT;

사용 시 주의점

  • SET TRANSACTION은 트랜잭션 시작 전에만 사용할 수 있다. 즉 BEGIN 또는 START TRANSACTION이전에 설정해야 한다.
  • DBMS마다 기본 격리 수준이 다르므로 명시적으로 설정하면 더 안전하다.
    • MySQL은 기본적으로 REPEATABLE READ이고, ProstgreSQL은 기본적으로 READ COMMITED이다.
profile
백엔드 개발자를 목표로 공부하는 대학생

0개의 댓글