이 글은 해당 글을 바탕으로 내용을 추가하여 올리는 글입니다 !!
병행 제어 (Concurrency Control)
병행 제어란 여러개의 트랜잭션이 실행될 때 트랜잭션들이 데이터베이스의 일관성을 파괴하지 않고 다른 트랜잭션에 영향을 주지 않으면서 트랜잭션을 제어하는 것을 말한다.
매우 빠르게 트랜잭션 사이를 이동하면서 조금씩 처리를 수행하는 방식이다.
실제로는 한번에 한 트랙잭션만 수행하지만 마치 동시에 여러 트랜잭션을 수행하는 것처럼 보인다.
병행제어의 목적
- 데이터베이스의 공유와 시스템 활용도의 최대화
- 데이터베이스의 일관성 유지
- 사용자에 대한 응답시간을 최소화
- 단위 시간당 트랜잭션 처리수 최대화
트랜잭션이 동시에 실행된다면 ?
Dirty Write
같은 데이터에 대해 동시에 두 개 이상의 트랜잭션이 값을 바꾸고자 할 때 발생되는 현상
Dirty Read
아직 종료(commit)되지 않은 트랜잭션의 쓰기 내용을 읽는 것으로 비정상적 상태의 데이터를 읽게 되는 현상
Non-repeatable Read
어떤 트랜잭션에서 동일한 데이터의 값을 읽을 때 마다 매번 결과값이 달라지는 현상
Phantom Read
기존 데이터는 동일한 데 새로 추가된 값에 의해 데이터 값이 변경되는 현상
병행 제어를 하지 않는다면 ?
병행 제어를 하지 않고 트랜잭션들이 동시에 데이터베이스에 접근할 수 있다면 여러 문제점이 발생한다.
갱신 분실 (Lost Update)
갱신 분실이란 같은 데이터에 대해 둘 이상의 트랜잭션이 동시에 갱신할 때, 갱신 결과의 일부가 없어지는 현상이다.
두개의 트랜잭션이 수행될 때 최종 결과는 x + 800이 더해져야 한다.
하지만 같은 데이터인 x에 대해서 트랜잭션 1이 갱신하기 전에 트랜잭션 2가 x값을 받아와서 결국 최종 결과는 x + 500이 되어버린다.
이렇게 둘 이상의 트랜잭션이 동시에 같은 데이터를 갱신하면 올바르게 갱신되지 못한다.
모순성 (Inconsistency)
모순성은 하나의 트랜잭션이 여러 데이터 갱신 연산을 수행할 때, 일관성 없는 상태의 데이터베이스에서 데이터를 가져옴으로써 데이터의 불일치가 발생하는 것을 의미한다.
다음 상황에서 트랜잭션 1이 완료되기 전에 트랜잭션 2가 수행되고 있다.
최종 결과로는 4 * (y + 500)의 결과가 나와야 하지만 (4 * y) + 500 결과값이 나오는 모순이 발생한다.
트랜잭션 2의 입장에서는 일관성이 유지되지만 트랜잭션 1의 입장에서는 실행 전후 차이가 500만큼이 아닌 그보다 더 큰 차이가 발생하기 때문에 데이터의 불일치가 발생한다.
연쇄 복귀 (Cascading Rollback)
연쇄 복귀는 병행 수행되던 둘 이상의 트랙잭션 중 어느 한 트랜잭션에 오류가 발생하여 Rollback 하는 경우 다른 트랜잭션도 함게 Rollback되는 현상을 말한다.
회복 불가 (Unrecoverable)
복수의 트랜잭션이 Data 공유 시 특정 Transaction이 처리의 취소를 하고자 할 때, 다른 Transaction이 처리한 부분에 대해서는 취소 불가한 상태 발생
비완료 의존성 (Uncommitted Dependency, Dirty Read 라고도 한다.)
하나의 트랜잭션 수행이 실패한 후 회복하기 전에 다른 트랜잭션이 실패한 갱신 결과를 참조하는 현상을 말한다.
트랜잭션의 중간 수행 결과를 다른 트랜잭션이 참조함으로써 발생하는 오류
병행 제어 기법
구분 | 제어 기법 | 내용 |
Locking | Shared Lock | 데이터 항목에 대해 읽기만 가능 |
Exclusive Lock | 데이터 항목에 대해서 읽기와 기록(입력/삭제)가 모두 불가능 | |
2 Phase Locking(2PL) | 모든 트랜잭션들이 lock과 unlock연산을 확장 단계와 수축 단계로 구분하여 수행함 | |
Timestamp Ordering | DB시스템에 들어오는 트랜잭션 순서대로 System Clock / Logical Counter 할당하고 순서를 부여하여 동시성 제어의 기준으로 사용 | |
Validation(낙관적 검증) | 트랜잭션 수행 동안은 어떠한 검사도 하지 않고, 트랜잭션 종료 시 일괄적 검사 기법 | |
MVCC (다중버전 동시성 제어) |
트랜잭션의 타임스탬프와 접근 데이터의 여러 버전 타임스탬프 비교하여 직렬 가능성이 보장되는 버전 선택 |
로킹 (Locking)
로킹은 트랜잭션이 접근하려는 데이터를 다른 트랜잭션이 접근하지 못하도록 Lock 하는 병행 제어 기법이다.
이를 통해 상호 배제(Mutual Exclusive) 기능을 제공하며 잠금을 설정한 트랜잭션이 unlock 할 때까지 데이터를 독점적으로 사용할 수 있다.
한번에 로킹할 수 있는 데이터의 크기를 로킹 단위라고 하며 필드(Field), 레코드(Record), 테이블(Table), 파일(File), 데이터베이스(Database) 모두 로킹 단위가 될 수 있다.
로킹 단위의 크기에 따라 성능의 차이가 발생한다.
로킹 단위가 클수록 병행 제어가 단순해지고 관리하기가 편하지만 병행성 수준이 낮아진다.
반면 로킹 단위가 작을수록 병행 제어가 복잡해지고 오버헤드가 증가하지만 병행성 수준이 높아지고 데이터베이스 공유도가 높아진다.
로킹 규약
1) 트랜잭션 T가 공유 데이터 x를 접근하려면 먼저 lock(x)을 해야 한다.
2) 공유 데이터를 사용한 T는 반드시 unlock(x)을 해야 한다.
3) 다른 트랜잭션에 의해 lock(x)가 실행되었다면, 트랜잭션 T는 lock(x)을 실행하지 못한다.
4) 트랜잭션 T가 lock(x) 한 것을 다른 트랜잭션이 unlock(x)할 수 없다.
하나의 트랜잭션만이 공유 데이터를 사용할 수 있는데 실제로 오직 읽기(read)만 하는 경우에는 동시에 접근해도 문제가 없기 때문에 이런 경우에는 효율적이지 못하다.
따라서 위와 같은 문제점을 해결하기 위해 사용되는 것이 2단계 로킹 규약이다.
로킹 기법은 교착 상태가 발생할 수 있다는 한계가 있다.
다음과 같이 트랜잭션 T1에서 x를 lock 하고 T2에서 y를 lock 한 경우에 T1도 y에 접근할 수도 없고 T2도 x에 접근할 수 없다.
따라서 서로 무한정 기다리게 된다.
2단계 로킹 규약 (Two-Phase Locking, 2PL)
2단계 로킹 규약은 각 트랜잭션의 lock과 unlock 요청을 2단계로 실시하는 방식이다.
단계는 확장 단계(Growing Phase)와 축소 단계(Shrinking Phase)로 나뉜다.
이는 직렬성을 보장하는 대표적인 로킹 규약이지만 여전히 lock 연산으로 인한 교착상태를 예방할 수는 없다.
- 확장 단계(Growing phase) : 새로운 lock 연산만을 수행할 수 있고 unlock 연산은 수행할 수 없는 단계
- 축소 단계(shrinking phase) : unlock 연산을 수행할 수 있고 lock 연산은 수행할 수 없는 단계
타임스탬프 순서 기법 (Timestamp ordering)
타임스탬프 순서 기법은 비직렬 트랜잭션을 타임스탬프 순서에 따라 직렬화 시키는 방법이다.
데이터에 접근하는 시간(TimeStamp)을 미리 정해두어 부여된 시간 순서대로 데이터에 접근하여 lock을 사용하지 않고 시간을 나눠 사용하기 때문에 교착상태가 발생하지 않는다.
하지만 Rollback 발생률이 높고 연쇄 복귀를 초래할 수 있는 단점이 있다.
낙관적 병행 제어 (Optimistic Concurrency Control)
낙관적 병행 제어는 트랜잭션 수행 동안은 어떠한 검사를 하지 않고 트랜잭션이 종료된 이후에 일괄적으로 검사하는 방식이다.
다중 버전 병행 제어 (Multi-version Concurrency Control)
한 데이터에 대해 여러 버전의 값을 유지하며 관리하는 방식이다.
타임스탬프의 개념을 이용하며 다중 버전 타임 스탬프 기법이라고도 한다.
참고
'CS > 데이터베이스' 카테고리의 다른 글
[데이터베이스] 무결성 (Integrity) (0) | 2022.07.26 |
---|---|
[데이터베이스] 트랜잭션의 격리 수준 (0) | 2022.07.26 |
[데이터베이스] 트랜잭션 (Transaction) (0) | 2022.07.22 |
[데이터베이스] 정규화 (Normalization) (0) | 2022.07.22 |
[데이터베이스] Index (인덱스) (0) | 2022.07.22 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!