Transaction

김기현·2025년 6월 19일

Database

목록 보기
21/24

트랜잭션이란 데이터베이스의 하나의 논리적인 작업 단위로, 여러 SQL문장이 하나의 단위로 묶여 모두 성공하거나 모두 실패해야 한다.

START TRANSACTION;

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

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

COMMIT;

위와 같은 이체 작업은 두 쿼리가 모두 성공해야 의미가 있으며, 하나라도 실패하면 전체를 ROLLBACK해야 한다.

트랜잭션의 4가지 속성

Atomicity (원자성)

트랜잭션은 모든 작업이 전부 수행되거나, 전혀 수행되지 않아야 한다.

  • 트랜잭션 안의 모든 작업은 하나의 단위로 간주된다.
  • 도중에 오류가 발생하면 전체 작업을 되돌려야 한다.
  • 성공 시에는 모든 변경이 반영된다.
START TRANSACTION;

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

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

COMMIT;

여기서 한 줄이라도 실패하면 ROLLBACK해야 원자성이 보장된다.

Consistency (일관성)

트랜잭션 전후에 데이터는 항상 일관된 상태여야 한다.

  • 데이터는 무결성 제약조건을 항상 만족해야 한다.(PK, FK, 제약조건 등)
  • 트랜잭션 처리 전과 후에 데이터베이스 규칙이 지켜져야 한다.
은행에서 A가 B에게 이체를 한다면 전체 계좌의 총합은 변하지 않아야 한다. 
데이터의 무결성과 제약조건이 항상 유지되어야 일관성이 유지된다.

Isolation (고립성)

동시에 실행되는 트랜잭션이 서로 간섭하지 않아야 한다.

  • 하나의 트랜잭션은 다른 트랜잭션의 중간 상태를 볼 수 없어야 한다.
  • 트랜잭션 격리 수준과 밀접한 관련이 있다.
  • 격리 수준이 낮을수록 성능은 좋아지지만, 이상현상이 발생할 수 있다.

Durability (지속성)

트랜잭션이 성공적으로 끝나면 그 결과는 영구적으로 저장되어야 한다.

  • 트랜잭션이 COMMIT된 이루에는 시스템 장애가 나더라도 데이터는 유지되어야 한다.
  • 데이터는 디스크 등에 영구히 저장되며, DB가 복구되더라도 보존된다.
  • DBMS는 WAL(Write-Ahead Logging)등으로 이를 구현한다.
어떤 계좌에서 돈을 이체하고 COMMIT 된 직후 전원이 꺼지더라도,
그 이체는 반영된 상태로 남아있어야 한다.

트랜잭션 명령어

START TRANSACTION; -- 트랜잭션 시작

COMMIT; -- 트랜잭션 성공으로 변경 내용을 영구 반영한다.

ROLLBACK; -- 트랜잭션 실패로 변경 내용을 모두 취소한다.
  • MySQL은 BEGINSTART TRANSACTION과 동일하게 사용된다.

트랜잭션 격리 수준

격리 수준은 동시 실행되는 트랜잭션들이 서로 간섭하지 않도록 하기 위한 설정이다. 4가지 표준 격리 수준이 있으며, 낮은 수준일수록 성능은 좋지만 일관성 문제가 발생할 수 있다.

수준설명허용되는 이상 현상
READ UNCOMMITTED다른 트랜잭션이 커밋하지 않은 데이터도 읽음Dirty Read, Non-repeatable Read, Phantom Read
READ COMMITTED커밋된 데이터만 읽을 수 있음Non-repeatable Read, Phantom Read
REPEATABLE READ트랜잭션 동안 읽은 값은 항상 동일Phantom Read
SERIALIZABLE모든 트랜잭션을 순차적으로 실행 (가장 안전, 가장 느림)없음

이상 현상 정의

이상 현상설명
Dirty Read커밋되지 않은 데이터를 읽음
Non-repeatable Read같은 SELECT를 했는데 결과가 바뀜
Phantom Read조건에 맞는 행의 개수가 바뀌는 현상 (ex. SELECT COUNT(*)가 다르게 나옴)

트랜잭션 격리 수준 설정

MySQL 기준의 예지이다.

-- 전역 설정 (MySQL 재시작 전까지 유지한다)
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 세션 설정 (현재 연결에만 적용)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

트랜잭션 사용 시 유의점

  • 트랜잭션은 꼭 필요한 경우에만 사용한다. 지나치게 오래 열려있으면 락 문제가 발생할 수 있다.
  • 일관성과 성능의 균형을 고려하여 격리 수준을 선택해야 한다.
  • 오류 발생 시 반드시 ROLLBACK처리 해야한다.
profile
백엔드 개발자를 목표로 공부하는 대학생

0개의 댓글