24.02.02 TIL - transaction Lock
1. 락(Lock)
락은 동시성을 제어하기 위해 사용하는 기능이다. 해당하는 데이터를 점유하여 다른 트랜잭션의 접근을 막아 일관성의 균형을 맞추기 위해 사용한다.
하나의 데이터를 여러 사용자들이 동시에 변경하려고 할 때, 한번에 여러번의 수정이 발생하게 되어 최종 수정된 결과값을 인지할 수 없게 되고 데이터베이스의 일관성이 깨지게 되는 것을 방지하기 위함이다.
1) 종류
a) 공유 락(Shared Locks) = 읽기 락(READ Locks)
다른 트랜잭션이 데이터를 읽는 것은 허용하지만, 수정하는 것은 금지다. READ 전용 락이라고 불리기도 하며, 해당 락을 사용하는 트랜잭션이 모든 작업을 수행하였다면 공유 락은 해제됩니다.
b) 배타 락(Exclusive Locks) = 쓰기 락(WRITE Locks)
다른 트랜잭션이 데이터를 읽거나, 수정하는 것을 금지합니다. WRITE 전용 락이라고 불리며, 트랜잭션이 해당하는 데이터를 점유한 후, 다른 트랜잭션이 해당 데이터에 접근 할 수 없도록 만듭니다.
2) 락킹 수준(Locking Level)
a) 글로벌 락(Global Locks) | 데이터베이스 락(Database Locks)
데이터베이스의 모든 테이블에 락을 걸어, 현재 트랜잭션을 제외한 나머지 트랜잭션들이 모든 테이블을 사용할 수 없도록 만듭니다. 가장 높은 수준의 락을 가지고 있으며, 가장 큰 범위를 가지고 있습니다.
b) 테이블 락(Table Locks)
다른 사용자가 작업중인 테이블을 동시에 수정하지 못하도록 합니다.
c) 네임드 락(Named Locks)
테이블이나 테이블의 행과같은 DB 오브젝트가 아닌, 특정한 문자열을 점유합니다.
d) 메타데이터 락(Metadata Locks)
다른 사용자가 작업중인 테이블의 동일한 행 및 동일한 데이터베이스의 객체를 동시에 수정하지 못하도록 합니다.
※ 교착상태(Dead Lock)
여러 테이블에 락(Lock)을 적용하여, 다른 작업이 처리되지 못하게 점유하고 있는 작업이 있을 때, 다른 작업을 끝나는 것을 무한정 기다리는것을 나타낸다. 잘못된 락 설정을 하게 될 경우 발생하고, 모든 API가 동작하지 않을 수 있다. 따라서 트랜잭션에서 사용하는 락(Lock)의 수준을 명확하게 이해하고, 적재적소에 필요한 락의 수준을 설정하여 트랜잭션을 구성해야한다.
2. 트랜잭션의 격리 수준 (Isolation Level)
격리 수준은 여러 트랜잭션이 동시에 처리될 때 다른 트랜잭션에서 변경 및 조회하는 데이터를 읽을 수 있도록 허용하거나 거부하는 것을 결정하기 위해 사용하는 것 입니다. 중요한 점은 ‘데이터의 일관성’과 ‘동시성 처리 성능’ 사이에서 균형을 잡는 것입니다.
a) READ UNCOMMITTED
다른 트랜잭션에 의해 작업중인 데이터를 읽게 되는 커밋 되지 않은 읽기(Uncommitted Read)를 허용하는 격리 수준입니다. 가장 낮은 수준의 격리수준이며, 락을 걸지 않아 동시성이 높지만, 의도치 않은 데이터를 참조하게 되어 일관성이 쉽게 깨질 수 있습니다.
b) READ COMMITTED
커밋 된 읽기(Committed Read)만을 허용하고, SELECT 문을 실행할 때 공유락을 겁니다. 다른 트랜잭션이 데이터를 수정하고 있는 중에는 데이터를 읽을 수 없어 커밋되지 않은 읽기현상이 발생하지 않습니다.
c) REPEATABLE READ
읽기를 마치더라도 공유락을 풀지 않으며, 트랜잭션이 완전히 종료될 때 까지 락을 유지합니다. 공유락이 걸린 상태에서 데이터를 수정하는 것은 불가능하지만, 데이터를 삽입하는 것이 가능해집니다. 그로인해 트랜잭션을 수행하던 중 다른 트랜잭션에 의해 삭제된 데이터를 읽게 되는 팬텀 읽기가 발생할 수 있는 문제점이 있습니다.
d) SERIALIZABLE
데이터를 읽는 동안 다른 트랜잭션이 해당 데이터를 읽거나 삽입할 수 없고, 새로운 데이터를 추가하는 것 또한 불가능합니다.가장 높은 수준의 격리 수준이므로, 동시성이 떨어지는 문제점이 존재합니다.