트랜잭션

개발자되고싶은데·2025년 11월 14일

SQLD 트랜잭션(Transaction) 완벽 정리

트랜잭션이란?

트랜잭션은 데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위입니다. 여러 개의 SQL 문장들이 모여 하나의 트랜잭션을 구성하며, 이들은 모두 성공하거나 모두 실패해야 합니다.

실생활 예시: 계좌 이체

A 계좌에서 B 계좌로 10만원을 이체하는 경우:
1. A 계좌에서 10만원 차감
2. B 계좌에 10만원 추가

이 두 작업은 반드시 함께 성공하거나 함께 실패해야 합니다. 만약 A 계좌에서만 돈이 빠지고 B 계좌에 입금되지 않는다면 큰 문제가 발생하겠죠?

트랜잭션의 4가지 특성 (ACID)

1. 원자성 (Atomicity)

  • All or Nothing: 트랜잭션의 모든 연산이 완전히 수행되거나, 전혀 수행되지 않아야 함
  • 중간에 실패하면 트랜잭션 시작 전 상태로 롤백(Rollback)
BEGIN TRANSACTION;
UPDATE account SET balance = balance - 100000 WHERE id = 'A';
UPDATE account SET balance = balance + 100000 WHERE id = 'B';
-- 둘 다 성공해야만 COMMIT, 하나라도 실패하면 ROLLBACK
COMMIT;

2. 일관성 (Consistency)

  • 트랜잭션 실행 전후로 데이터베이스가 일관된 상태를 유지해야 함
  • 무결성 제약조건을 만족해야 함
  • 예: 잔액은 음수가 될 수 없다는 제약이 있다면, 트랜잭션 후에도 이 조건이 유지되어야 함

3. 격리성 (Isolation)

  • 여러 트랜잭션이 동시에 실행될 때, 각 트랜잭션은 독립적으로 실행되는 것처럼 보여야 함
  • 한 트랜잭션의 중간 결과가 다른 트랜잭션에 영향을 주지 않음
  • 격리 수준(Isolation Level)에 따라 동시성 제어 정도가 달라짐

4. 지속성 (Durability)

  • 트랜잭션이 성공적으로 완료(COMMIT)되면, 그 결과는 영구적으로 반영되어야 함
  • 시스템 장애가 발생해도 커밋된 데이터는 보존됨

트랜잭션 제어 명령어 (TCL)

COMMIT

  • 트랜잭션의 모든 작업을 확정하여 데이터베이스에 영구 반영
  • COMMIT 이후에는 변경사항을 되돌릴 수 없음
BEGIN TRANSACTION;
INSERT INTO orders VALUES (1, '상품A', 50000);
UPDATE inventory SET stock = stock - 1 WHERE product = '상품A';
COMMIT; -- 변경사항 확정

ROLLBACK

  • 트랜잭션의 모든 작업을 취소하고 이전 상태로 복구
  • 트랜잭션 시작 전 또는 마지막 COMMIT 시점으로 되돌아감
BEGIN TRANSACTION;
DELETE FROM orders WHERE order_id = 100;
-- 실수로 잘못 삭제한 경우
ROLLBACK; -- 삭제 취소, 원상복구

SAVEPOINT

  • 트랜잭션 내에 중간 저장점을 설정
  • 전체 롤백이 아닌 특정 SAVEPOINT까지만 롤백 가능
BEGIN TRANSACTION;
INSERT INTO orders VALUES (1, '상품A', 30000);
SAVEPOINT sp1;

INSERT INTO orders VALUES (2, '상품B', 50000);
SAVEPOINT sp2;

INSERT INTO orders VALUES (3, '상품C', 70000);

-- 상품C 주문만 취소하고 A, B는 유지
ROLLBACK TO sp2;

COMMIT; -- 상품A, B 주문만 확정

트랜잭션의 상태

  1. 활동(Active): 트랜잭션이 실행 중인 상태
  2. 부분 완료(Partially Committed): 마지막 연산이 실행된 직후 상태
  3. 완료(Committed): 트랜잭션이 성공적으로 완료되어 COMMIT된 상태
  4. 실패(Failed): 정상적인 실행이 더 이상 불가능한 상태
  5. 철회(Aborted): 트랜잭션이 롤백되고 트랜잭션 이전 상태로 복구된 상태

격리 수준 (Isolation Level)

격리 수준이 높을수록 데이터 무결성은 보장되지만, 동시성은 낮아집니다.

1. READ UNCOMMITTED (레벨 0)

  • 커밋되지 않은 데이터를 읽을 수 있음
  • Dirty Read 발생 가능

2. READ COMMITTED (레벨 1)

  • 커밋된 데이터만 읽을 수 있음
  • Non-Repeatable Read 발생 가능
  • Oracle, SQL Server의 기본 격리 수준

3. REPEATABLE READ (레벨 2)

  • 트랜잭션 내에서 같은 데이터를 여러 번 읽어도 동일한 값 보장
  • Phantom Read 발생 가능
  • MySQL(InnoDB)의 기본 격리 수준

4. SERIALIZABLE (레벨 3)

  • 가장 높은 격리 수준
  • 모든 이상 현상 방지
  • 동시성이 가장 낮음

트랜잭션 이상 현상

Dirty Read (오손 읽기)

  • 커밋되지 않은 데이터를 읽는 현상
  • 트랜잭션 A가 수정 중인 데이터를 트랜잭션 B가 읽음

Non-Repeatable Read (반복 불가능 읽기)

  • 한 트랜잭션 내에서 같은 데이터를 두 번 읽었는데 값이 다른 현상
  • 트랜잭션 A가 데이터를 읽은 후, 트랜잭션 B가 해당 데이터를 수정/삭제하고 커밋

Phantom Read (유령 읽기)

  • 한 트랜잭션 내에서 같은 조건으로 조회했는데 결과 행의 개수가 다른 현상
  • 트랜잭션 A가 조회한 후, 트랜잭션 B가 새로운 행을 삽입하고 커밋

실무 활용 팁

1. 트랜잭션은 최소 단위로

-- 나쁜 예: 트랜잭션이 너무 큼
BEGIN TRANSACTION;
SELECT * FROM large_table; -- 시간이 오래 걸리는 조회
UPDATE orders SET status = 'completed';
COMMIT;

-- 좋은 예: 필요한 부분만 트랜잭션으로
SELECT * FROM large_table; -- 트랜잭션 밖에서 조회
BEGIN TRANSACTION;
UPDATE orders SET status = 'completed';
COMMIT;

2. 명시적 트랜잭션 사용

-- Auto Commit 모드가 아닌 경우 명시적으로 제어
BEGIN TRANSACTION;
-- SQL 작업들
COMMIT; -- 또는 ROLLBACK

3. 에러 처리

BEGIN TRY
    BEGIN TRANSACTION;
    -- SQL 작업들
    COMMIT;
END TRY
BEGIN CATCH
    ROLLBACK;
    -- 에러 처리
END CATCH

SQLD 시험 대비 핵심 정리

✅ ACID 특성 암기: 원자성, 일관성, 격리성, 지속성

✅ TCL 명령어: COMMIT, ROLLBACK, SAVEPOINT

✅ 격리 수준 순서: READ UNCOMMITTED < READ COMMITTED < REPEATABLE READ < SERIALIZABLE

✅ 이상 현상: Dirty Read, Non-Repeatable Read, Phantom Read

✅ 트랜잭션 상태: Active → Partially Committed → Committed 또는 Failed → Aborted

느낀점

TCL은 데이터베이스에서 트랜잭션을 제어하기 위한 명령어로 SQL 문으로 수행된 작업을 저장하거나 취소하는 역할을 한다.
정말 어려운 것같다

0개의 댓글