[TIL 2021.09.18] 데이터베이스 개론: 병행 제어concurrency control

Kyu·2021년 9월 18일
0

TIL

목록 보기
251/322

Today I Learned
데이터베이스 트랜잭션에서 병행 제어에 대해 배웠다.

DBMS는 여러 사용자가 동시에 데이터를 조작할 수 있게 여러 개의 트랜잭션이 동시에 수행 되는 병행 수행(concurrency)를 지원한다.

병행 수행을 지원하는 것에는 문제가 없지만 같은 데이터를 동시에 갱신하려하다 의도하는 결과와 다른 결과를 받을 수 있다.

대표적으로 갱신분실(lost update), 모순성(inconsistency), 연쇄 복귀(cascading rollback)이 있다.

갱신분실은 같은 데이터에 트랜잭션들이 접근하여 덮어쓰는 현상을 말한다.

예를들어 트랜잭션1은 기존에 있는 A의 통장잔고를 1000원 올려주는 트랜잭션이고, 트랜잭션2는 기존에 있는 A의 통장잔고에 0.1을 곱하는 트랜잭션이라고 가정해보자.

기존 A의 잔고: 3000원

T1: read(A) <-- A: 3000원
T1: A = A + 1000 <-- result: 4000원
T2: read(A) <-- A: 3000원
T2: A = A * 0.1 <-- result: 300원
T1: write(A) <-- A: 4000원
T2: write(A) <-- A: 300원

결과적으로 A는 300원이 된다.

이것을 T1에 대해 갱신 분실이 발생한다고 표현한다.

하지만 두 트랜잭션이 동시에 수행되지 않고 순차적으로 수행된다면?

기존 A의 잔고: 3000원

T1: read(A) <-- A: 3000원
T1: A = A + 1000 <-- result: 4000원
T1: write(A) <-- A: 4000원
T2: read(A) <-- A: 4000원
T2: A = A * 0.1 <-- result: 400원
T2: write(A) <-- A: 400원

결과적으로 A는 400원이 된다.

이처럼 두 트랜잭션이 동시에 수행하더라도 순차적으로 수행한것과 같은 결과 값을 얻을수있어야 정확한 병행 수행이라고 한다.

모순성이나 연쇄 복귀도 갱신 분실의 예처럼 데이터조작이 의도치 않게 되는 것을 말한다.

이런 문제들이 발생하지 않고 정확한 수행 결과를 얻을 수 있게 하는 것이 병행 제어(concurrency control)이다.

병행제어에서 중요한 포인트는 연산 순서이다.

트랜잭션 스케줄은 트랜잭션에 포함되어있는 연산들을 수행하는 순서이다.

트랜잭션 스케줄에는 직렬 스케줄(serial schedule), 비직렬 스케줄(nonserial schedule), 직렬 가능 스케줄(serializable schedule)이 있다.

직렬 스케줄은 각 트랜잭션별로연산들을 순차적으로 실행시키는 것이다.
(이게 인터리빙 방식 아니였나?)

직렬 스케줄은 인터리빙 방식을 사용하지 않고 각 트랜잭션을 독립적으로 수행하기 땜에 병행 수행이라고 할수없다. 그래서 직렬 스케줄은 일반적으로 잘 사용하지 않는다.

비직렬 스케줄은 트랜잭션이 돌아가면서 연산을 하기때문에 하나의 트랜잭션이 완료되기전에 다른 트랜잭션의 연산이 실행될수있어서 아까 말한 여러 문제가 발생해 최종 결과의 정확성을 보장할 수 없다.

직렬 가능 스케줄은 정확한 결과를 생성하는 비직렬 스케줄이다. DBMS는 직렬 가능 스케줄인지를 검사하기보다 직렬 간으성을 보장하는 병행제어기법을 사용한다.

병행제어기법은 여러 트랜잭션을 벙행 수행하면서도 정확한 겨로가를 얻을수있는 직렬 가능성을 보장받기 위해 사용한다.

병행제어기법중 가장 많이 사용하는 것은 로킹(locking) 기법이다.

트랜잭션을 실행하면서 데이터를 read하기전에 그 데이터에 대해서 lock을 하는 것이다. lock을 하는 범위는 좁게는 그 데이터의 속성이 될수도 있고 데이터베이스 그 자체가 될수도 있다.

데이터베이스 자체를 lock하면 제어가 간단하지만 하나의 트랜잭션만 수행될수있으므로 병행수행이라고 할수없다. 하지만 lock의 범위를 좁히면 제어가 어렵지만 병행성은 높아진다. 시스템에 따라 적절한 로킹 단위를 선택하는 것이 중요하다.

기본 로킹 규약은 그럼에도 직렬 가능성을 보장하지 못하는데 이를 보완한 것이 2단계 로킹규약(2PLP; 2 Phase Locking Protocol)이다. 이를 사용하면 직렬 가능성을 보장할수있지만 교착상태(deadlock)이 발생할수있다.

deadlock이란 트랜잭션 서로가 lock에 걸린 데이터가 unlock되기를 기다리는 상태로 무한대기에 빠지는 상태를 말한다.

profile
TIL 남기는 공간입니다

0개의 댓글