[DB/SQL] 트랜잭션과 동시성 제어

songeunm·2025년 6월 7일

DB & SQL

목록 보기
22/27

🎱 트랜잭션

⚽️ 정의

  • Transaction
  • 하나의 논리적 작업 단위
  • 데이터베이스에서 모두 성공하거나 모두 실패해야 하는 연산 집합

⚽️ 특징 - ACID

  • A - Atomicity - 원자성
    • 전부 수행되거나 전부 수행되지 않아야 함
  • C - Consistency - 일관성
    • 트랜잭션 전후에 데이터 무결성이 유지되어야 함
  • I - Isolation - 고립성
    • 동시에 실행되는 트랜잭션은 서로 영향을 주지 않아야 함
  • D - Durability - 지속성
    • 커밋된 결과는 시스템 장애에도 유지되어야 함

⚽️ 트랜잭션 명령어

  • BEGIN / START TRANSACTION
    • 트랜잭션 시작

      DBMS트랜잭션 시작 문법
      MySQLSTART TRANSACTION or BEGIN
      PostgreSQLSTART TRANSACTION or BEGIN
      Oracle명시적 BEGIN 없음 (자동 트랜잭션)
      MSSQLBEGIN TRANSACTION
      SQLiteBEGIN TRANSACTION or BEGIN
  • COMMIT
    • 트랜잭션 확정 → 데이터 반영
  • ROLLBACK
    • 트랜잭션 취소 → 데이터 복구
  • SAVEPOINT
    • 중간 저장점 설정
    • 세이브포인트는 중간에 커밋하면 사라짐
  • ROLLBACK TO SAVEPOINT
    • 저장점까지 롤백
    • 세이브포인트로 롤백 이후 트랜잭션 계속 진행 가능
-- 트랜잭션 정상 수행 (TRANSACTION - COMMIT)
START TRANSACTION;

-- 출금
UPDATE BankAccount
SET Balance = Balance - 30000
WHERE AccountId = 1;

-- 입금
UPDATE BankAccount
SET Balance = Balance + 30000
WHERE AccountId = 2;

COMMIT;
-- 트랜잭션 롤백 (TRANSACTION - ROLLBACK)
START TRANSACTION;

-- 출금
UPDATE BankAccount
SET Balance = Balance - 30000
WHERE AccountId = 1;

-- 입금 (에러 발생)
UPDATE BankAccount
SET Balance = Balance + 30000
WHERE AccountId = 2222222;

ROLLBACK;
-- 세이브포인트 롤백 (SAVEPOINT - ROLLBACK TO SAVEPOINT)
START TRANSACTION;

-- 출금
UPDATE BankAccount
SET Balance = Balance - 30000
WHERE AccountId = 1;

SAVEPOINT BeforeDeposit;

-- 입금 (에러 발생)
UPDATE BankAccount
SET Balance = Balance + 30000
WHERE AccountId = 2222222;

ROLLBACK TO BeforeDeposit;

COMMIT;

🎱 동시성 제어

⚽️ 정의

  • Concurrency Control
  • 여러 사용자가 동시에 데이터에 접근할 때 정합성을 보장하고 충돌을 방지하기 위한 기술

⚽️ 동시성 제어 방식

  • Locking 잠금
    • 데이터에 대해 공유/배타적 잠금 설정
    • 공유 잠금 (S-lock, Shared Lock)
      • 다른 트랜잭션들의 읽기만 허용, 쓰기는 차단
      • SELECT → S-lock
      • ex) 트랜잭션이 읽은 데이터에 공유 락(S-lock)을 설정
        → 트랜잭션 도중 해당 값이 바뀌지 않도록 함
    • 배타 잠금 (X-lock, Exclusive Lock)
      • 다른 트랜잭션의 읽기/쓰기 전부 차단
      • UPDATE, DELETE, INSERT → X-lock
      • ex) 트랜잭션이 값을 변경중인 데이터에 배타 락(X-lock) 설정
        → 다른 트랜잭션이 값을 읽을 수도 변경할 수도 없음
  • MVCC 다중 버전 동시성 제어
    • 트랜잭션마다 데이터의 스냅샷을 따로 제공 → 충돌 감소
  • 사용
    • Oracle, PostgreSQL → MVCC
    • MySQL(InnoDB) → MVCC + Lock

⚽️ 동시성 문제 종류

  • Dirty Read
    • 다른 트랜잭션이 아직 COMMIT하지 않은 데이터를 읽음
  • Non-repeatbale Read
    • 같은 쿼리 실행 시 중간에 다른 사용자에 의해 업데이트되어 결과가 달라짐
  • Phantom Read
    • 같은 쿼리 실행 시 중간에 다른 사용자에 의해 삽입/삭제되어 조건에 맞는 행의 수가 달라짐

⚽️ 해결 방법 - 격리 수준

  • 트랜잭션 간의 독립성 수준을 설정
  • 높을수록 안전성 ⬆️ 처리 성능 ⬇️
  • 수준
    • Read Uncommitted
      • 커밋되지 않은 데이터 읽기 허용
      • 예방 문제
        • X
    • Read Committed
      • 커밋된 데이터만 읽기 허용
      • 예방 문제
        • Dirty Read
    • Repeatable Read
      • 같은 조건일 경우 같은 결과 보장
      • 구현
        • Lock 기반 DBMS
          • S-lock 유지
        • MVCC 기반 DBMS
          • 스냅샷 고정
      • 예방 문제
        • Dirty Read
        • Non-repeatble Read
    • Serializable
      • 완벽 격리 (잠금 or 정렬 기반)
      • 구현
        • Lock 기반 DBMS
          • 범위 잠금까지 사용
          • 범위 잠금: 조건식 기반 데이터 영역 전체에 락
        • MVCC 기반 DBMS
          • 범위검사 + 쓰기 차단/지연 + 충돌 탐지
      • 예방 문제
        • Dirty Read
        • Non-repeatble Read
        • Phantom Read
profile
데굴데굴 구르는 개발자 지망생

0개의 댓글