데이터베이스 이론 - 트랜잭션(Transaction)
Chapter 17: Transactions (Database System Conceptys 7th Edition) 을 공부하고 정리한 글 입니다.
# 트랜잭션 이란?
Single logical unit of work
데이터베이스 운영상 하나로 묶여야할 로직들을 모은 것
ex. 은행 송금 예시 (A가 B에게 10불을 송금한다.)
1. A의 잔액에서 10불을 차감한다.
2. B의 잔액에 10불을 더한다.
"송금"로직에서 이 두 과정은 하나의 논리적인 작업으로 묶여야 하고, 1,2 과정 중 하나만 반영되거나 그래선 안 됨
# 트랜잭션의 특징 - ACID 원칙
앞선 송금 예시처럼 트랜잭션은 다음 네 가지 원칙 지켜야한다.
Atomicity
트랜잭션은 한번에 반영되거나 전체 반영되지 않아야 한다. (All or Noting)
=> 송금 이 실패하더라도 A의 잔액이 10불 차감된건 반영되지 않아야 함
Consistency
데이터의 일관성을 보장해야 한다.
Isolation
트랜잭션은 각각 서로 영향이 없어야 한다 (한 트랜잭션이 다른 트랜잭션에 영향을 미쳐서는 안 된다.)
Durability
트랜잭션이 한 번 반영되면 영구적으로 저장되어야 한다.
# 트랜잭션의 동시성 문제
여러개의 트랜잭션을 동시에 수행할 때 문제가 발생하지 않도록 하는 개념들을 소개한다.
# 직렬 가능성 (Serializability)
각 트랜잭션이 "동시에" 수행되더라도 "순차적"으로 실행된 결과와 동일한 스케줄(=다수의 트랜잭션에 실행되는 순서)
스케줄을 직렬가능하도록 만드는 것이 트랜잭션을 동시에 수행하더라도 일관성을 보장할 수 있는 방법이다.
# 충돌 직렬 가능성 (Conflict Serializability)
서로 다른 트랜잭션이 하나의 데이터에 연속된 연산 중 쓰기 연산이 한 번이라도 포함되면 이를 충돌이라고 표현한다.
비충돌 연산은 수행 순서를 교환하더라도 무방하다. (결과에 영향을 미치지 않는다.)
충돌 연산이 있는 트랜잭션의 비충돌 연산 순서를 적절히 변경시켜서 직렬 가능 스케줄로 만들 수 있다면, 이를 충돌 직렬 가능성 스케줄 이라고 부른다.
# 직렬 가능성은 어떻게 알아보는가?
충돌 직렬가능성인 경우 Precedence graph를 사용한다. 해당 그래프를 그렸을때 cycle이 나오면 충돌 직렬 가능하지 않은 스케줄이다.
# 회복 가능 스케줄 (Recoverable Schedule)
트랜잭션 T1, T2가 동일 데이터를 T1 -> T2 순으로 접근하는 스케줄이라면, 회복 가능 스케줄은 T1 커밋 후 T2 커밋이 이루어지는 스케줄을 말한다.
# Cascading Rollbacks
하나의 트랜잭션 롤백이 다른 트랜잭션 롤백을 야기하는 현상. 이는 다른 트랜잭션에서 커밋한 데이터만 읽게 하므로써 방지할 수 있다.
# 트랜잭션 격리 수준
트랜잭션을 동시에 수행할 때 데이터베이스는 저장된 데이터의 일관성을 잃으면 안된다. (트랜잭션의 일관성 원칙)
따라서 데이터의 일관성을 보장할 수 있게끔 몇가지 트랜잭션 격리 단계가 존재한다.
Read Uncommitted - 커밋되지 않는 데이터에 접근 가능
장점 : 없음
문제점 : Dirty read(커밋되지 않은 데이터 변경을 읽을 수 있는 문제), Nonrepeatable read, 직렬하지 않은 스케줄 발생 가능
Read Committed - 커밋된 데이터만 접근 가능
장점 : Dirty read 방지
문제점 : Nonrepeatable read, 직렬하지 않은 스케줄 발생 가능
Repeatable Read - 커밋된 데이터만 접근 가능, 중복 읽기 지원(읽을때 항상 동일한 값을 보장)
장점 : Dirty read 방지, Repeatable read 보장
문제점 : 직렬하지 않은 스케줄 발생 가능, 팬텀 읽기 문제 발생 가능 (없던 레코드가 갑자기 생기는 것)
Serializable - 커밋된 데이터만 접근 가능, 중복 읽기 지원, 팬텀 읽기 문제 없음 (=순차적으로 수행한 결과와 동일한 결과를 보장)
장점 : Dirty read 방지, Repeatable read 보장, 팬텀 읽기 문제 없음, 직렬한 결과 보장
상용 DB의 디폴트 값은 다들 다르지만, Repeatable read ~ Serializable로 설정되어 있다.
높은 수준의 격리 수준일 수록 동시성(Concurrency = 성능)은 떨어지지만, 더 높은 수준의 일관성을 보장한다.