DBMS/MySQL

MySQL 트랜잭션: 데이터 무결성을 지키는 마법

우 선 2025. 3. 25. 17:44

1. 트랜잭션의 기본 개념

트랜잭션이란 무엇인가?

트랜잭션은 데이터베이스에서 하나의 논리적인 작업 단위를 의미한다. 마치 은행 송금과 같이 여러 작업이 모두 성공하거나 모두 실패해야 하는 상황을 다룬다.

ACID 원칙

트랜잭션의 핵심은 ACID 원칙이다:

  • Atomicity(원자성): 모든 작업이 완전히 수행되거나 전혀 수행되지 않아야 한다.
  • Consistency(일관성): 트랜잭션 실행 전후 데이터베이스의 상태는 일관성을 유지해야 한다.
  • Isolation(격리성): 동시에 실행되는 트랜잭션들은 서로 영향을 미치지 않아야 한다.
  • Durability(지속성): 한번 완료된 트랜잭션의 결과는 영구적으로 저장된다.

2. 트랜잭션 기본 사용법

트랜잭션 시작과 종료

-- 트랜잭션 시작
START TRANSACTION;

-- 또는
BEGIN;

-- 계좌 이체 예시
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 2;

-- 성공 시 변경 확정
COMMIT;

-- 실패 시 롤백
ROLLBACK;

예금 이체 시나리오

-- 안전한 계좌 이체 트랜잭션
DELIMITER //

CREATE PROCEDURE transfer_money(
    IN from_account INT, 
    IN to_account INT, 
    IN transfer_amount DECIMAL(10,2)
)
BEGIN
    -- 트랜잭션 시작
    START TRANSACTION;
    
    -- 예외 핸들러 선언
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        -- 오류 발생 시 롤백
        ROLLBACK;
        RESIGNAL;
    END;
    
    -- 출금 계정에서 금액 차감
    UPDATE accounts 
    SET balance = balance - transfer_amount 
    WHERE id = from_account AND balance >= transfer_amount;
    
    -- 입금 계정에 금액 추가
    UPDATE accounts 
    SET balance = balance + transfer_amount 
    WHERE id = to_account;
    
    -- 모든 작업 성공 시 커밋
    COMMIT;
END //

DELIMITER ;-- 안전한 계좌 이체 트랜잭션
DELIMITER //

CREATE PROCEDURE transfer_money(
    IN from_account INT, 
    IN to_account INT, 
    IN transfer_amount DECIMAL(10,2)
)
BEGIN
    -- 트랜잭션 시작
    START TRANSACTION;
    
    -- 예외 핸들러 선언
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        -- 오류 발생 시 롤백
        ROLLBACK;
        RESIGNAL;
    END;
    
    -- 출금 계정에서 금액 차감
    UPDATE accounts 
    SET balance = balance - transfer_amount 
    WHERE id = from_account AND balance >= transfer_amount;
    
    -- 입금 계정에 금액 추가
    UPDATE accounts 
    SET balance = balance + transfer_amount 
    WHERE id = to_account;
    
    -- 모든 작업 성공 시 커밋
    COMMIT;
END //

DELIMITER ;

3. 트랜잭션 격리 수준

격리 수준의 종류

  1. READ UNCOMMITTED: 가장 낮은 격리 수준
  2. READ COMMITTED: 커밋된 데이터만 읽기 가능
  3. REPEATABLE READ: MySQL 기본 격리 수준
  4. SERIALIZABLE: 가장 높은 격리 수준
-- 격리 수준 설정
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 현재 격리 수준 확인
SELECT @@transaction_isolation;

격리 수준별 문제점

  • Dirty Read: 커밋되지 않은 데이터 읽기
  • Non-Repeatable Read: 같은 데이터 반복 조회 시 다른 값
  • Phantom Read: 트랜잭션 중 새로운 행 추가/삭제

4. 동시성 제어

락(Lock)의 이해

-- 명시적 테이블 락
LOCK TABLES users WRITE;

-- 레코드 락
SELECT * FROM users WHERE id = 1 FOR UPDATE;

-- 락 해제
UNLOCK TABLES;

낙관적 락 vs 비관적 락

  • 낙관적 락: 충돌 가능성이 낮다고 가정
  • 비관적 락: 충돌 가능성을 미리 방지

5. 고급 트랜잭션 패턴

세이브포인트 사용

START TRANSACTION;

-- 첫 번째 작업
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;

-- 세이브포인트 생성
SAVEPOINT transfer_point;

-- 두 번째 작업
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;

-- 특정 지점으로 롤백 가능
ROLLBACK TO SAVEPOINT transfer_point;

COMMIT;

나의 트랜잭션 학습 여정

트랜잭션을 배우면서 느낀 점은, 이것이 단순한 기술적 메커니즘을 넘어 데이터의 신뢰성을 지키는 중요한 방어선이라는 것이다.

은행 송금, 온라인 결제, 주문 시스템 등 우리 주변의 수많은 중요한 시스템들이 트랜잭션의 원리 위에 구축되어 있다.

데이터베이스는 단순한 저장소가 아니라, 우리의 디지털 세계를 안전하게 지키는 수호자와 같다.

'DBMS > MySQL' 카테고리의 다른 글

데이터베이스 설계  (0) 2025.03.25
MySQL 인덱스와 DDL 깊이 파보기  (0) 2025.03.25
MySQL 고급 기능 마스터하기  (0) 2025.03.25
MySQL 기본 문법 완전 정복  (0) 2025.03.25