DB 트랜잭션과 LOCK
DB Transaction
- 논리적인 작업의 단위(사용자 입장)
계좌 이체
등
- 데이터베이스의 상태를 변경하는 작업의 단위(시스템 입장)
트랜잭션
으로 묶인 연산들은All Or Nothing
- 모두 실행되거나 모두 실행되지 않거나.- 트랜잭션의 설계가 중요하다.
Transaction과 lock의 차이
- Transaction -
정합성
을 보장하기 위한 기능 - Lock -
동시성
을 제어하기 위한 기능
트랜잭션이 지켜야하는 원칙 - ACID
원자성(Atomic, All or Nothing)
- 하나의
트랜잭션
을 이루는연산들
은 모두 실행되거나 모두 실행되지 않거나
일관성(Consistency)
- 트랜잭션의 실행이 완료되면 데이터베이스는
일관된 상태
를 유지 - 트랜잭션이 완료될 때 여러 제약조건에 맞는 상태를 보장해야하는 성질
- 성공적으로 수행된 트랜잭션은 정당한 데이터들만을 데이터베이스에 반영해야 한다.
- 트랜잭션 전/후의 데이터베이스 상태는
각각 일관성이 보장되는 서로 다른 상태
가 되어야 한다.- ex: A, B간 계좌 이체 시 트랜잭션 전/후의 A, B 잔고 상태는 다르지만 총합은 같다.
명시적인 일관성
은 기본키, 외래키 제약과 같은명시적인 무결성 제약 조건
비명시적 일관성
은 “계좌 이체 후 두 계좌의 잔고 합이 같아야 한다”와 같은 일관성
독립성, 격리성(Isolation)
- 하나의 트랜잭션이 수행되는 동안 다른 트랜잭션이 끼어들 수 없다. (동시성 문제)
- 여러 트랜잭션이
동시
에 수행되더라도 각각의 트랜잭션은 다른 트랜잭션의 수행에 영향을 받지 않고독립적
으로 수행되어야 한다. - 한 트랜잭션의
중간 결과
가 다른 트랜잭션에게 숨겨져야 한다. - 트랜잭션이 진행되는
중간 상태의 데이터
를 다른 트랜잭션이 볼 수 없도록 보장 격리 레벨
로 설정 가능하다.
ACID 원칙은 완벽히 지켜지지 않는다. - Transaction의 Isolation Level
실제로 ACID 원칙
은 종종 지켜지지 않는다. ACID 원칙을 strict 하게 지키려면 동시성
이 매우 떨어지기 때문
그렇기 때문에 보통 DB 엔진은 ACID 원칙을 조금 희생하여 동시성
을 얻을 수 있는 방법을 제공한다. 바로 Transaction Isolation Level
Isolation
원칙을 덜 지키는 level
을 사용할 수록 문제가 발생할 가능성은 커지지만 더 높은 동시성을 얻을 수 있다.
DB 엔진은 Isolation Level
에 따라 서로 다른 Locking 전략
을 취한다. 요컨대 isolation level
이 높아질수록 더 보수적인 Lock을 거는 것이다.
Lock
Oracle을 비롯한 대부분의 DB는 Transaction의 ACID 원칙
과 동시성
을 최대한 보장하기 위해 다양한 종류의 LOCK
을 사용한다.
- Row-level lock
- 가장 기본적인
lock
은 테이블의row
마다 걸리는row-level lock
이다. - 여기에는 크게
shared-lock(s-lock)
과exclusive-lock(x-lock)
이 존재한다.
- 가장 기본적인
- shared-lock
read(=select)
에 대한lock
이다. 일반적으로SELECT
쿼리는 동일한 리소스(table row
)에 동시에 사용(접근)이 가능하다.- 다시말해 여러 Transaction이 동시에 동일한 row에
s-lock
을 걸 수 있다. - 하지만
s-lock
이 걸린 row에 대해서는x-lock
이 불가능하다.
- exclusive-lock
write(update, delete)
에 대한lock
이다.- x-lock이 걸려있는
row
에는 다른 Transaction들이s-lock
이나x-lock
을 걸 수 없다. - 즉, x-lock이 걸려있는
row
는 다른 트랜잭션들이read
,write
모두 불가능하다.
요약하자면 s-lock
을 사용하는 트랜잭션끼리는 동일한 row에 접근이 가능하다. 반면 x-lock
이 걸린 row는 다른 어떤 트랜잭션도 접근이 불가능하다.
Lock 해제 타이밍
Transaction
이 진행되는 동안 수 많은 lock
들을 데이터베이스에 걸게 된다.
이러한 lock
들은 모두 transaction commit
또는 rollback
될 때 함께 unlock
된다.
트랜잭션 사용 시 주의
- 트랜잭션은 꼭 필요한
최소의 코드
에만 적용되어야 한다. → 트랜잭션의 범위를 최소화- 단위 스레드가
커넥션 소유 시간이 길어진다
면 다른 스레드가 커넥션 획득을 위해 대기해야 하는 상황이 발생
- 단위 스레드가
교착 상태
발생 가능- 복수의 트랜잭션 사용 시 각 트랜잭션이 사용하는 자원에
LOCK
을 걸고 서로의 자원을 요구하면DEAD LOCK
이 발생
- 복수의 트랜잭션 사용 시 각 트랜잭션이 사용하는 자원에