[Database] 동시성 처리
Exclusive Lock은 락을 소유한 트랜잭션만 해당 데이터 항목을 읽거나 쓸 수 있고, 다른 트랜잭션들은 그 데이터 항목에 대해 접근을 차단한다.
Shared Lock은 여러 트랜잭션이 동시에 같은 데이터 항목을 읽을 수 있도록 허용하지만 해당 데이터 항목이 읽기 작업 중 변경됨을 방지한다.
보통 트랜잭션의 격리 수준으로 간접적으로 락의 동작 방식을 제어할 수 있고, SELECT ... FOR UPDATE / LOCK IN SHARE MODE 구문을 사용해 쿼리 수준에서 명시적으로 락을 요청할 수도 있다.
예약 사이트를 개발하는 경우 이중 예약이 불가능해야 하니.. SELECT ... FOR UPDATE 구문으로 조회 쿼리에서도 명시적으로 Exclusive Lock을 사용하자.
데이터베이스의 동시성을 처리할 때 락이 중요한 요소로 작용하는데, 락의 내부 동작 방식은 데이터베이스마다 다르니 사용하는 데이터베이스가 락을 어떻게 다루는지 파악해야 한다.
예를 들면..
MySQL의 InnoDB는 행 수준 락을 사용해 동시성을 지원하고 SQL Server는 트랜잭션 격리 수준에 따라 페이지 레벨 / 테이블 수준 락을 동적으로 사용한다.
데이터를 처리하기 전에 미리 잠금을 거는 방식인 Pessimistic Lock과 데이터가 변경되지 않았음을 가정하는 Optimistic Lock은 동시성을 관리할 때 사용되는 전략이다.
Exclusive Lock과 Shared Lock은 데이터베이스 내부 락 매커니즘이고 Pessimistic Lock과 Optimistic Lock은 데이터베이스 시스템에 내장된 기능이 아니라 개발자가 선택할 수 있는 동시성 제어 전략으로 이해하자.
Pessimistic Lock 전략에서 데이터를 읽을 때는 Shared Lock을 사용해 여러 트랜잭션이 동시에 데이터를 읽을 수 있도록 하고, 데이터를 변경할 때는 Exclusive Lock을 사용해 Exclusive Lock을 보유하는동안 다른 트랜잭션이 데이터를 읽을 수 없도록 설정한다.
Optimistic Lock 전략은 데이터베이스의 내부 Lock 매커니즘을 직접 사용하기보다는 백엔드에서 직접 데이터의 버전을 관리하는 방식으로 구현되는데, 데이터를 변경하는 시점에 해당 데이터가 마지막으로 읽힌 이후 변경됐는지 확인한다.
데이터의 충돌 가능성이 높은 경우 Pessimistic Lock 전략을, 데이터를 조회하는 쿼리가 많고 변경 충돌이 발생할 확률이 적은 경우 Optimistic Lock 전략을 사용하자.
MVCC (Multi Version Concurrency Control)는 동시성 제어 매커니즘으로 Pessimistic Lock과 Optimistic Lock 전력을 보완하거나 함께 사용할 수 있는 도구이다.
트랜잭션이 데이터를 읽을 때 MVCC는 해당 트랜잭션의 시점에 해당하는 데이터의 버전을 제공하는데, 이 버전을 통해 다른 트랜잭션이 데이터를 변경하더라도 읽기 작업이 일관된 데이터를 바라보도록 한다.
트랜잭션이 데이터를 변경할 때 새로운 데이터 버전을 제공하고, 트랜잭션이 커밋되면 새로운 버전이 현재 버전으로 활성화돼 다른 트랜잭션이 새로운 버전을 볼 수 있다.
데이터의 여러 버전을 유지해야 해 추가적인 저장 공간이 필요하고, 더 이상 사용되지 않는 데이터 버전을 정리하기 위해 가비지 컬렉션을 사용해야 한다.
특정 데이터베이스 시스템은 트랜잭션 격리 수준을 구현하기 위해 내부적으로 MVCC를 사용하는데..
PostgreSQL, MySQL의 InnoDB, Oracle이 READ COMMITTED 이상의 격리 수준을 구현할 때 MVCC를 사용한다.
정리하면..
락으로 트랜잭션 격리 수준을 구현하는 데이터베이스가 있고 (SQL Server)
MVCC로 트랜잭션 격리 수준을 구현하는 데이터베이스가 있으며 (PostgreSQL, MySQL InnoDB)
락과 MVCC를 모두 사용해 트랜잭션 격리 수준을 구현하는 데이터베이스가 있다. (Oracle)
그리고 Pessimistic Lock과 Optimistic Lock은 동시성을 다루는 전략이고
Shared Lock과 Exclusive Lock은 데이터베이스가 사용하는 락 매커니즘이다.
한 데이터베이스에서 A와 B가 동시에 작업한다고 가정하자.
A가 트랜잭션을 시작하고 테이블에 1이라는 값을 추가했고, 이 트랜잭션은 해당 행에 대한 Exclusive Lock을 획득했다.
A가 시작한 트랜잭션을 커밋하기 전 B가 트랜잭션을 시작하고 테이블에 2라는 값을 추가한 후 테이블에 1이라는 값을 추가하려 할 때 B도 해당 행에 대한 Exclusive Lock을 요청하는데, A가 이미 락을 보유하고 있기에 B는 A가 시작한 트랜잭션이 끝날 때 까지 대기하게 된다.
여기서 A가 2라는 값을 추가하려 시도하면 A와 B가 모두 서로가 보유한 리소스에 대한 Lock 해제를 대기하게 돼 데드락이 발생한다.
대부분의 데이터베이스 시스템은 데드락 상황을 감지하고 자동으로 트랜잭션을 롤백시킨다.
'Database > Database' 카테고리의 다른 글
[Database] Database Engine (0) | 2024.04.17 |
---|---|
[Database] Sharding (0) | 2024.04.08 |
[Database] Partitioning (0) | 2024.04.04 |
[Database] B+Tree 자료구조 (0) | 2024.03.30 |
[Database] 내부 저장 구조 (0) | 2024.01.29 |
댓글
이 글 공유하기
다른 글
-
[Database] Database Engine
[Database] Database Engine
2024.04.17 -
[Database] Sharding
[Database] Sharding
2024.04.08 -
[Database] Partitioning
[Database] Partitioning
2024.04.04 -
[Database] B+Tree 자료구조
[Database] B+Tree 자료구조
2024.03.30