1. 트랜잭션 개요

1.1. 트랜잭션

  • 트랜잭션(Transaction)의 정의
    • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 논리적인 단위이다.
    • 여러 개의 SQL 연산(INSERT, UPDATE 등)이 모여 하나의 트랜잭션을 구성하며, 이들은 모두 성공하거나 모두 실패해야 한다. (All or Nothing)

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

  1. 원자성(Atomicity)

    • 트랜잭션 내의 연산은 모두 반영되거나, 전혀 반영되지 않아야 한다.
    • (완료되지 않으면 ROLLBACK)
  2. 일관성(Consistency)

    • 트랜잭션 수행 전후에 데이터베이스는 일관된 상태(제약조건 만족 등)를 유지해야 한다.
    • 수행 도중에는 일시적으로 불일치할 수 있다.
  3. 고립성(Isolation)

    • 현재 수행 중인 트랜잭션이 완료될 때까지 다른 트랜잭션이 중간 연산 결과에 접근할 수 없다.
  4. 지속성(Durability)

    • 성공적으로 완료(Commit)된 트랜잭션의 결과는 시스템 장애가 발생하더라도 영구적으로 보존되어야 한다.
특성의미동시성 제어회복
원자성(Atomicity)트랜잭션 내 모든 연산은 수행되거나 수행되지 않음-O
일관성(Consistency)트랜잭션 전/후의 데이터베이스 상태는 항상 일관성 있음O-
고립성(Isolation)동시에 실행되는 트랜잭션은 서로 독립적임O-
지속성(Durability)완료된 트랜잭션은 데이터베이스에 영구적으로 반영됨-O

1.3. 연산 종류

  • COMMIT: 트랜잭션의 변경 내용을 DB에 영구 반영하고 완료함.
  • ROLLBACK: 트랜잭션의 변경 내용을 취소하고 수행 전 상태로 되돌림(원자성 보장).

2. 동시성 제어

  • 동시성 제어(Concurrency Control)의 필요성
    • 다수의 사용자가 동시에 DB에 접근할 때, 트랜잭션 간의 간섭으로 인해 부정확한 결과가 생기지 않도록 제어하는 기법이다.

2.1. 동시성 제어가 없을 때 발생하는 문제

  1. 갱신 손실(lost update)

    • 두 트랜잭션이 같은 데이터를 동시에 갱신할 때,
    • 나중의 갱신이 먼저의 갱신을 덮어써서 손실되는 현상
  2. 오손 읽기(dirty read)

    • 한 트랜잭션의 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 현상
    • READ COMMITTED 고립 수준에서 불가능
  3. 반복 불가능한 읽기(non-repeatable read)

    • 한 트랜잭션이 같은 데이터를 두 번 읽을 때,
    • 그 사이에 다른 트랜잭션이 값을 갱신하여 다른 값을 읽는 현상
    • REPEATABLE READ 고립 수준에서 불가능
  4. 유령 읽기(phantom read)

    • 한 트랜잭션 내에서 범위 쿼리를 반복 수행할 때,
    • 다른 트랜잭션의 삽입(INSERT)으로 인해 없던 데이터가 나타나는 현상
    • SERIALIZABLE 고립 수준에서 불가능

2.2. 제어 기법: 로킹(Locking)

  • 로크의 종류

    • Shared-lock (S-lock; 공유 로크)
      • 읽기(Read) 목적
      • 다른 공유 로크와 양립 가능
    • Exclusive-lock (X-lock; 독점 로크)
      • 갱신(Write) 목적
      • 다른 어떤 로크와도 양립 불가(상호 배제)
  • 2단계 로킹 프로토콜 (2PL; 2-phase locking)

    • 확장 단계: 로크를 얻기만 하고 해제는 하지 않음
    • 수축 단계: 로크를 해제하기만 하고 새로운 로크는 얻지 않음
    • 특징: 직렬 가능성을 보장하지만 교착상태(Deadlock)가 발생할 수 있음

2.3 다중 로크 단위(Multiple Granularity)

  • DB, 테이블, 블록, 튜플 등 로크를 거는 단위의 크기를 조절한다.
    • 단위가 작을수록 병행성(동시성)은 증가하지만, 오버헤드가 커진다.
    • 단위가 클수록 병행성은 감소하지만, 오버헤드는 줄어든다.

3. 회복

3.1. 회복

  • 회복(Recovery)의 개념

    • 장애(시스템 다운, 디스크 오류 등) 발생 시 데이터베이스를 일관성 있는 상태로 복구하는 기법이다.
  • 회복을 위한 데이터베이스 사본

    • 로그(Log): 변경 연산 기록을 별도의 파일에 유지하여 회복에 사용한다.
    • 덤프(Dump): 데이터베이스 전체를 주기적으로 복사한다.

3.2. 회복 기법

  • 회복을 위한 연산

    1. UNDO(취소) - 원자성 보장
      • 장애 발생 시점까지 완료되지 않은 트랜잭션의 변경 내용을 취소
    2. REDO(재수행) - 지속성 보장
      • 장애 발생 전 완료(Commit)된 트랜잭션의 내용을 로그를 이용해 다시 실행
  • 로그 레코드의 유형

    • [Trans-ID, start]
      • 한 트랜잭션이 생성될 때 기록되는 로그 레코드
    • [Trans-ID, X, old_value, new_value]
      • 주어진 Trans_ID를 갖는 트랜잭션이
      • 데이터 항목 X를 이전값(old_value)에서 새값(new_value)로 수정했음을 나타내는 로그 레코드
    • [Trans-ID, commit]
      • 주어진 Trans_ID를 갖는 트랜잭션이
      • 데이터베이스에 대한 갱신을 모두 성공적으로 완료하였음을 나타내는 로그 레코드
    • [Trans-ID, abort]
      • 주어진 Trans_ID를 갖는 트랜잭션이 철회되었음을 나타내는 로그 레코드
  • 로그 회복 기법

    • 즉시 갱신(Immediate Update)
      • 수행 중 변경 내용을 즉시 DB와 로그에 반영
      • COMMIT 전 장애 시 UNDO 수행
      • COMMIT 후 장애 시 REDO 수행
    • 지연 갱신(Deferred Update)
      • COMMIT 전까지는 로그에만 기록하고 DB 반영을 지연
      • 장애 시 REDO만 수행 (UNDO 불필요)

3.3. 체크포인트

  • 로그 먼저 쓰기(WAL; Write-Ahead Logging)

    • 로그 버퍼를 데이터베이스 버퍼보다 먼저 디스크에 기록해야 함 (시스템 다운 대비)
  • 체크포인트(Checkpoint)

    • 주기적으로 주기억장치(버퍼)의 내용을 디스크에 강제로 기록하고 로그와 동기화하는 시점
    • 회복 시 체크포인트 이후의 로그만 처리하면 되므로 회복 시간을 단축시킨다.
  • 체크포인트를 할 때 수행되는 작업

    • 주기억 장치의 로그 버퍼를 디스크에 강제로 출력
    • 주기억 장치의 데이터베이스 버퍼를 디스크에 강제로 출력
    • checkpoint 로그 레코드를 로그 버퍼에 기록한 후 디스크에 강제로 출력

4. PL/SQL의 트랜잭션

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

  • COMMIT: 변경 사항 저장 및 트랜잭션 종료
  • ROLLBACK: 변경 사항 전체 취소 및 트랜잭션 종료
  • SAVEPOINT: 트랜잭션 내 중간 저장점 설정
  • ROLLBACK TO SAVEPOINT: 특정 저장점까지만 부분적으로 취소

4.2. 고립 수준(Isolation Level)

SQL 표준 및 오라클에서 제공하는 트랜잭션 고립 수준에 따라 발생 가능한 문제가 다르다.

고립 수준
(Level)
오손 데이터 읽기
(Dirty Read)
반복 불가 읽기
(Unrepeatable Read)
팬텀 문제
(Phantom Read)
READ UNCOMMITTED가능가능가능
READ COMMITTED불가능가능가능
REPEATABLE READ불가능불가능가능
SERIALIZABLE불가능불가능불가능
  • READ COMMITTED: 오라클의 기본 설정이다.
  • SERIALIZABLE: 가장 높은 수준으로 완벽한 일관성을 제공하지만 동시성이 가장 낮다.
  • SET TRANSACTION READ ONLY: 읽기 전용 트랜잭션으로 설정하여 DBMS의 동시성 처리 성능을 높일 수 있다.