변수의 기록
(데이터베이스) 트랜잭션 스케줄링과 Serializability 정리 본문
트랜잭션이 동시에 실행될 때, 우리는 무엇을 보장해야 할까?
데이터베이스에서 여러 사용자가 동시에 트랜잭션을 수행한다면 어떤 일이 벌어질까요?
예를 들어, 두 명의 사용자가 동시에 같은 은행 계좌에 접근해 금액을 업데이트한다고 가정해봅시다.
T1: 1000원을 출금
T2: 2000원을 입금
정상이라면 결과는 잔고 +1000원이 되어야겠지만, 두 트랜잭션이 얽혀 실행되면 예기치 못한 결과가 발생할 수 있습니다. 이처럼 트랜잭션의 실행 순서는 단순히 성능을 넘어서 데이터의 정확성과 직결됩니다.
스케줄(Schedule)이란?
스케줄은 여러 트랜잭션이 동시에 실행될 때, 각 연산(읽기, 쓰기)이 실제로 어떤 순서로 실행되었는지를 기록한 것입니다.
중요한 점은:
- 각 트랜잭션 내부의 연산 순서는 바뀌지 않지만
- 여러 트랜잭션이 뒤섞여 실행될 수 있다는 점입니다.
그렇다면 어떤 스케줄이 안전할까?
1. Serial Schedule
가장 단순하고 안전한 방식은 트랜잭션을 순차적으로 한 개씩 실행하는 것입니다.
T1: 모든 연산 → 완료 후
T2: 모든 연산 → 실행
이 방식은 일관성은 보장되지만, 성능은 낮습니다.
실제로는 거의 사용되지 않습니다.
2. Non-Serial Schedule
현실 세계에서는 성능을 위해 여러 트랜잭션을 겹쳐서 동시에 실행합니다.
T1: 일부 연산
T2: 일부 연산
T1: 나머지 연산
T2: 나머지 연산
이 방식은 성능은 좋지만, 의도치 않은 충돌이 발생할 수 있습니다.
대표적인 문제가 바로 아래의 Lost Update입니다.
Lost Update: 덮어쓰기 사고
T1: read A (값 10) → A = A + 5 → write A (15)
T2: read A (값 10) → A = A + 10 → write A (20)
결과적으로 **T1의 변경사항(15)**은 완전히 사라지고, A는 20이 되어버립니다.
두 트랜잭션 모두 A를 읽고 수정했지만, 마지막에 쓰기(write)한 쪽만 남는 겁니다.
이걸 막기 위해 우리는 스케줄이 안전한지를 판단하는 기준이 필요합니다.
스케줄이 안전하다는 기준: Serializability
Serializability는 "이 스케줄이 어떤 순차적 실행(Serial Schedule)과 동일한 결과를 낸다면 안전하다"는 개념입니다.
즉, 겹쳐 실행은 하되, 결과는 마치 순차적으로 실행한 것처럼 보이게 하자.
어떻게 동일함을 판단할까? (Conflict Serializability)
Conflict란?
두 연산이 다음 조건을 모두 만족하면 **충돌(conflict)**입니다:
- 서로 다른 트랜잭션에 속하고
- 같은 데이터 항목을 접근하며
- 최소 하나는 write 연산이다.
Conflict Equivalent
- 두 스케줄이 같은 트랜잭션들로 구성되고
- 모든 충돌 연산들의 실행 순서가 동일하다면
→ 이 둘은 conflict equivalent하다고 합니다.
Conflict-Serializable
- 어떤 serial schedule과 conflict equivalent하다면
→ 그 스케줄은 conflict-serializable하다고 부릅니다.
이 기준은 단순하고 계산이 가능해서, 실제로 많은 DBMS가 사용하는 기준입니다.
Conflict Serializability 예제
두 개의 트랜잭션
T1: R1(A) W1(A) R1(B) W1(B)
T2: R2(A) W2(A)
- T1: A를 읽고 쓰고, B를 읽고 씀
- T2: A를 읽고 씀
📌 예제 스케줄 S1 (Non-Serial Schedule)
S1: R1(A) R2(A) W1(A) W2(A) R1(B) W1(B)
🔍 1. 충돌 연산 확인
- R1(A) vs W2(A) → conflict (T1 vs T2, 같은 A, W 포함)
- R2(A) vs W1(A) → conflict
- W1(A) vs W2(A) → conflict
→ 이들 연산 순서 확인 필요
🔍 2. conflict 연산 순서 (S1)
- R1(A) → W2(A)
- R2(A) → W1(A)
- W1(A) → W2(A)
충돌 순서들:
- T1 → T2 (R1(A) → W2(A))
- T2 → T1 (R2(A) → W1(A))
- T1 → T2 (W1(A) → W2(A))
→ 순환 발생: T1 → T2 → T1
→ conflict-serializable 하지 않다!
📌 예제 스케줄 S2 (Conflict-Serializable한 스케줄)
S2: R1(A) W1(A) R1(B) W1(B) R2(A) W2(A)
🔍 1. 충돌 연산 확인
- W1(A) vs R2(A) → conflict (T1 먼저)
- W1(A) vs W2(A) → conflict (T1 먼저)
→ T1의 모든 conflict write 연산이 T2보다 먼저 실행
→ T1 → T2 순서로 정렬됨 → 순환 없음
✅ S2는 conflict-serializable하다
→ T1 → T2 순차 실행과 동일한 결과
→ 이 스케줄은 Serial Schedule T1 → T2와 conflict equivalent함
요약
항목 | 설명 |
Conflict 조건 | 서로 다른 트랜잭션, 같은 데이터, 최소 하나 write |
Conflict-Equivalent | 충돌 순서가 동일하면 equivalent |
Conflict-Serializable | 어떤 시리얼 스케줄과 conflict-equivalent하면 OK |
충돌 순서에 순환 발생 시 | Conflict-Serializable 하지 않음 |
동시성 제어(Concurrency Control)의 목표
우리는 현실에서 트랜잭션을 동시에 실행시켜야 합니다.
하지만 동시에 실행하면서도 결과가 serializable하게 나와야 하죠.
그래서 DBMS는 다양한 동시성 제어 알고리즘을 사용합니다:
- 2-Phase Locking (2PL)
- Timestamp Ordering
- Optimistic Concurrency Control
이들 알고리즘은 각각의 방식으로 conflict-serializable한 스케줄을 보장합니다.
Isolation: 완벽하게 격리하고 싶지만…
Isolation은 트랜잭션이 마치 독립적으로 실행되는 것처럼 보장하는 속성입니다.
하지만 완벽한 격리는 성능에 큰 부담을 줍니다.
그래서 현실적인 절충안으로 Isolation Level이라는 개념이 등장합니다.
격리 수준 | 설명 | 발생 가능 문제 |
Read Uncommitted | 커밋되지 않은 데이터도 읽음 | Dirty Read, Non-repeatable Read |
Read Committed | 커밋된 데이터만 읽음 | Non-repeatable Read, Phantom Read |
Repeatable Read | 같은 데이터를 반복 조회해도 결과 동일 | Phantom Read 가능 |
Serializable | 가장 높은 수준, serial schedule과 동일 | 성능 저하 가능, 교착 상태 발생 가능성 |
Isolation Level은 DBMS 설정, JDBC, 혹은 Spring에서 설정 가능합니다.
정리
- 스케줄은 트랜잭션들이 어떤 순서로 실행되었는지를 보여주는 흐름이다.
- 시리얼 스케줄은 안전하지만 현실적이지 않고, non-serial은 현실적이지만 위험하다.
- serializability는 이러한 딜레마를 해결하는 이론적 기반이다.
- 특히 conflict-serializability는 실제 구현 가능한 기준이며, 많은 DBMS가 이 원칙을 기반으로 동작한다.
- 동시성 제어는 성능을 유지하면서도 데이터 정합성을 지키기 위한 핵심 기술이다.
- Isolation Level은 이 모든 것을 성능과 안전성 사이에서 조율하는 수단이다.
다음 추천 강의
'CS지식 > 데이터베이스 (Database)' 카테고리의 다른 글
(DB)트랜잭션 이상 현상 , Isolation Level 정리 (SQL-92 기준) (0) | 2025.05.20 |
---|---|
(데이터베이스) 트랜잭션 스케줄링 완전 분석: Recoverable, Cascadeless, Strict 스케줄의 모든 것 (0) | 2025.05.19 |
(데이터베이스) 트랜잭션과 ACID 완전 정리 (Oracle 중심 + Java 예제 포함) (0) | 2025.05.19 |
(데이터베이스)트리거(Trigger)란? — Oracle 기준으로 정리하는 SQL 트리거의 개념과 실무 주의사항 (0) | 2025.05.17 |
(데이터베이스 )Stored Procedure의 장단점과 일반 백엔드에서의 활용 시 주의점 (0) | 2025.05.17 |