트랜잭션 (Transaction)

mskimdev·2026년 4월 18일

MySQL

목록 보기
16/20
post-thumbnail

트랜잭션 (Transaction)

계좌 이체를 생각해보자. A가 B에게 10만 원을 보내는 과정은 두 단계다.

  1. A 계좌에서 10만 원 차감
  2. B 계좌에 10만 원 추가

그런데 1번은 성공했는데 2번 도중에 서버가 꺼지면 어떻게 될까. A의 돈은 빠져나갔는데 B에게는 입금이 안 된다. 이런 상황을 막기 위해 존재하는 것이 트랜잭션(Transaction)이다.

트랜잭션은 여러 쿼리를 하나의 작업 단위로 묶는다. 전부 성공하거나, 전부 실패하거나 — 둘 중 하나만 있다.


COMMIT과 ROLLBACK

트랜잭션의 핵심은 두 명령어다.

  • COMMIT — 트랜잭션 안의 모든 변경사항을 실제 DB에 반영한다
  • ROLLBACK — 트랜잭션 시작 전 상태로 되돌린다
-- 계좌 테이블 예시
CREATE TABLE account (
    id      INT PRIMARY KEY,
    name    VARCHAR(20),
    balance INT
);

INSERT INTO account VALUES (1, 'A', 100000);
INSERT INTO account VALUES (2, 'B', 50000);
-- 트랜잭션 시작
START TRANSACTION;

UPDATE account SET balance = balance - 100000 WHERE id = 1;
UPDATE account SET balance = balance + 100000 WHERE id = 2;

-- 문제 없으면 확정
COMMIT;

두 UPDATE가 모두 성공한 뒤 COMMIT하면 변경이 확정된다. 중간에 문제가 생겼다면 ROLLBACK으로 되돌린다.

START TRANSACTION;

UPDATE account SET balance = balance - 100000 WHERE id = 1;
-- 여기서 오류 발생 시

ROLLBACK;  -- A 계좌 차감도 없었던 일로 돌아간다


SAVEPOINT

트랜잭션 중간에 체크포인트를 만들 수 있다. 전체를 되돌리지 않고 특정 지점으로만 돌아가고 싶을 때 SAVEPOINT를 쓴다.

START TRANSACTION;

INSERT INTO account VALUES (3, 'C', 30000);
SAVEPOINT sp1;  -- 체크포인트 저장

INSERT INTO account VALUES (4, 'D', 20000);

-- D 추가는 취소하고 C 추가까지만 남기고 싶다면
ROLLBACK TO sp1;

COMMIT;  -- C만 추가된 상태로 확정

ROLLBACK TO sp1sp1 이후의 변경만 취소한다. sp1 이전 작업은 그대로 유지된다.


ACID

트랜잭션이 보장해야 하는 네 가지 성질이다. 앞 글자를 따서 ACID라고 부른다.

Atomicity (원자성)

트랜잭션 안의 작업은 전부 성공하거나 전부 실패한다. 계좌 이체에서 A 차감만 성공하고 B 입금이 실패하는 경우가 없도록 보장한다.

Consistency (일관성)

트랜잭션 전후로 DB의 제약 조건이 유지된다. 잔액이 음수가 되거나 FK가 깨지는 등 규칙에 어긋난 상태가 되지 않는다.

Isolation (격리성)

동시에 실행되는 트랜잭션은 서로 간섭하지 않는다. 내가 이체하는 도중 다른 사람이 같은 계좌를 조회해도 중간 상태가 보이지 않는다.

Durability (지속성)

COMMIT된 데이터는 시스템 장애가 발생해도 유지된다. 서버가 꺼져도 커밋한 내용은 사라지지 않는다.


AUTO COMMIT

MySQL은 기본적으로 AUTO COMMIT 모드다. 별도로 START TRANSACTION을 선언하지 않으면 쿼리 하나하나가 자동으로 COMMIT된다.

-- AUTO COMMIT 상태 확인
SELECT @@autocommit;  -- 1이면 AUTO COMMIT 켜진 상태

-- AUTO COMMIT 끄기
SET autocommit = 0;

-- AUTO COMMIT 다시 켜기
SET autocommit = 1;

AUTO COMMIT을 끄면 명시적으로 COMMIT을 해줘야 변경이 반영된다. START TRANSACTION을 쓰면 AUTO COMMIT 설정과 관계없이 해당 트랜잭션 블록 안에서는 수동 제어가 된다.


트랜잭션을 처음 접하면 "굳이 이게 왜 필요하지?"라는 생각이 든다. 데이터를 혼자 다루는 상황에선 크게 체감이 안 되기 때문이다. 하지만 여러 쿼리가 하나의 논리적 작업을 이루는 순간, 중간에 실패했을 때 데이터가 어떤 상태로 남는지가 중요해진다. 트랜잭션은 그 불확실성을 없애는 장치다.

profile
<- 개발 공부하는 나

0개의 댓글