오늘날의 데이터베이스 시스템은 수많은 사용자와 프로세스가 동시에 데이터를 접근하고 수정하는 복잡한 환경에서 운영됩니다.
이러한 환경에서 데이터의 무결성과 일관성을 유지하는 것은 매우 중요한 과제입니다.
만약 여러 사용자가 동시에 같은 데이터를 수정하려고 하면 데이터 손상, 일관성 문제, 비정상적인 결과가 발생할 수 있습니다. 이때 중요한 역할을 하는 것이 바로 DB Lock입니다.
DB Lock이란❓
DB Lock은 데이터베이스에서 여러 사용자나 프로세스가 동시에 동일한 데이터에 접근하거나 수정하려고 할 때 발생하는 문제를 방지하기 위해 사용되는 메커니즘입니다.
쉽게 말해, 데이터의 무결성과 일관성을 유지하기 위해 데이터베이스의 특정 자원(행, 테이블, 페이지 등)을 잠그는 과정입니다.
DB lock의 필요성
데이터 불일치(Inconsistent Data)
- 여러 트랜잭션이 동시에 동일한 데이터를 수정할 경우, 데이터의 일관성이 깨질 수 있습니다.
- 예를 들어, 두 명의 사용자가 동시에 같은 은행 계좌에 입금과 출금 작업을 하면, 올바른 최종 잔액이 기록되지 않을 수 있습니다.
더티 리드(Dirty Read)
- 한 트랜잭션이
아직 완료되지 않은다른 트랜잭션의 데이터를 읽는 경우 발생합니다. - 위와 같이 트랜잭션 1가 데이터를 수정한 후
아직 커밋되지 않았을 때, 트랜잭션 2가 수정된 데이터를 읽으면 잘못된 정보가 전달될 수 있습니다. 이후 트랜잭션 A가 롤백(취소)된다면, 트랜잭션 B는 잘못된 데이터를 기반으로 처리된 상태가 됩니다.
반복 불가능한 읽기(Non-repeatable Read)
- 한 트랜잭션 내에서 같은 데이터를 두 번 읽을 때, 그 사이에 다른 트랜잭션이 해당 데이터를 수정하면 서로 다른 결과를 얻게 됩니다.
- 예를 들어 위와 같은 그림에서 트랜잭션 1이 처음 데이터를 읽었을 때("Park")와 나중에 같은 데이터를 다시 읽었을 때 값이 달라지는 상황이 발생할 수 있습니다.
- 처음 : "Park"
- 나중 : "ZINU"
업데이트 손실(Lost Update)
- 두 개 이상의 트랜잭션이 동일한 데이터를 읽고, 그 데이터를 기반으로 수정 작업을 수행할 때 발생합니다.
- 예를 들어, 위와 같은 그림에서 트랜잭션 1의 수정 작업(10 -> 15)이 다른 트랜잭션 2의 업데이트에 의해 덮어씌워지면서 첫 번째 트랜잭션의 변경 내용(10 -> 20)이 유실되는 현상이 발생할 수 있습니다.
유령 데이터(Phantom Data)
- 한 트랜잭션이 특정 조건으로 데이터를 조회했을 때, 다른 트랜잭션이 새로운 데이터를 삽입하거나 기존 데이터를 삭제하면, 같은 조회 쿼리가 다른 결과를 반환할 수 있습니다.
- 예를 들어, 위와 같은 그림에서 첫 번째 조회에서 특정 조건(name = "ZINU" )을 만족하는 레코드가 1개였지만, 두 번째 조회에서는 2개가 될 수 있습니다.
데이터 손상(Corrupted Data)
- 여러 트랜잭션이 동시에 데이터를 수정하려고 하면, 데이터 손상이 발생할 수 있습니다.
- 특히, 동일한 데이터를 다른 트랜잭션이 동시에 수정하려고 하면 데이터가 완전히 망가질 위험이 있습니다.
- 예를 들어, 한 트랜잭션이 특정 필드를 10으로 설정하고 다른 트랜잭션이 동시에 같은 필드를 20으로 설정하면, 최종 값이 10과 20의 혼합된 잘못된 값으로 저장될 수 있습니다.
DB lock을 통해 데이터에 대한 접근을 제어하면, 위와 같은 상황에서 발생할 수 있는 데이터 무결성 문제를 예방할 수 있습니다.
DB Lock의 종류
공유 락(Shared Lock, S Lock)
데이터를 읽을 때 사용하는 락으로, 여러 트랜잭션이 동시에 데이터를 읽을 수 있지만, 데이터를 수정하려는 트랜잭션이 접근할 때는 기다려야 합니다.
- 상황
- 트랜잭션 A와 B가 동일한 상품의 가격을 조회합니다.
- 동작
- 두 트랜잭션 모두 상품 가격에 대해 공유 락을 얻습니다.
- 이 상태에서 트랜잭션 C가 가격을 수정하려고 하면, A와 B의 공유 락이 해제될 때까지 대기해야 합니다.
- 결과
- A와 B는 가격을 안전하게 읽을 수 있으며, C는 수정 작업을 안전하게 수행할 수 있습니다.
테이블 락(Table Lock)
특정 테이블 전체에 대한 락입니다. 테이블 락은 주로 테이블 구조를 변경하거나 대량의 데이터 작업을 수행할 때 사용됩니다.
- 상황
- 데이터베이스 관리자가 고객 테이블에 새로운 열(column)을 추가하려고 합니다.
- 동작
- 이 작업은 테이블 전체에 대한 락을 겁니다.
- 그동안 다른 트랜잭션은 해당 테이블에 접근하거나 수정할 수 없습니다.
- 결과
- 테이블 구조 변경이 완료되고 락이 해제되면, 다른 트랜잭션이 해당 테이블에 접근할 수 있습니다.
페이지 락(Page Lock)
데이터베이스의 특정 페이지(메모리 블록)를 잠그는 락입니다. 페이지는 여러 행을 포함할 수 있는 작은 데이터 블록입니다.
- 상황
- 데이터베이스에서 특정 페이지 내의 여러 행을 동시에 업데이트하려는 트랜잭션이 있습니다.
- 동작
- 이 트랜잭션은 해당 페이지 전체를 잠급니다.
- 이 동안 다른 트랜잭션은 동일한 페이지에 있는 데이터를 수정할 수 없습니다.
- 결과
- 페이지 단위의 동시성을 제어할 수 있으며, 다수의 행이 포함된 블록에 대한 작업이 안전하게 수행됩니다.
행 락(Row Lock)
특정 행(row)에 대한 접근을 잠그는 락으로, 주로 트랜잭션이 특정 행을 업데이트하거나 삭제할 때 사용됩니다.
- 상황
- 고객 데이터베이스에서 고객 ID가 123인 사용자의 주소를 업데이트하는 트랜잭션 A가 있습니다.
- 동작
- 트랜잭션 A는 고객 ID 123인 행을 잠급니다.
- 이 동안 다른 트랜잭션 B가 같은 행을 업데이트하려고 하면, 트랜잭션 A가 완료될 때까지 대기해야 합니다.
- 결과
- 트랜잭션 A가 주소를 성공적으로 업데이트하고 커밋하면, 트랜잭션 B가 그 후에 진행됩니다.
베타 락(Exclusive Lock)
데이터를 수정할 때 사용하는 락으로, 해당 자원에 대해 다른 트랜잭션이 어떤 작업도 할 수 없도록 잠급니다.\
- 상황
- 트랜잭션 A가 특정 상품의 가격을 업데이트하려고 합니다.
- 동작
- 트랜잭션 A는 해당 상품의 행에 대해 배타 락을 얻습니다.
- 다른 트랜잭션 B는 그 행에 대해 읽기, 수정하기 등
어떠한 작업도 할 수 없습니다.
- 결과
- 트랜잭션 A가 가격 업데이트를 완료하고 커밋할 때까지 다른 트랜잭션은 대기합니다.
- A가 커밋된 후, 다른 트랜잭션이 접근할 수 있습니다.
비관적 락(Pessimistic Lock)
비관적 락은 데이터 충돌이 자주 발생할 것으로 가정하고, 데이터에 접근할 때마다 잠금을 걸어 다른 트랜잭션이 동시에 접근하지 못하게 합니다.
- 상황
- 은행 계좌 이체 시스템에서 두 사용자가 동일한 계좌를 동시에 수정할 가능성이 높습니다.
- 동작
- 트랜잭션 A가 계좌 정보를 읽을 때 바로 비관적 락을 설정하여, 트랜잭션 B가 동일한 계좌 정보를 수정하려는 시도를 막습니다.
- 결과
- 트랜잭션 A가 작업을 완료하고 커밋할 때까지 다른 트랜잭션은 해당 계좌에 접근할 수 없으므로, 데이터 일관성이 보장됩니다.
낙관적 락(Optimistic Lock)
낙관적 락은 데이터 충돌이 드물 것이라고 가정하고, 데이터를 수정할 때만 충돌을 검사합니다. 트랜잭션이 데이터를 수정하기 전까지는 락을 걸지 않고, 수정 시점에 데이터가 변경되지 않았는지 확인합니다.
- 상황
- 제품 리뷰 시스템에서 사용자가 동일한 리뷰를 동시에 수정할 가능성이 낮습니다.
- 동작
- 트랜잭션 A가 리뷰를 조회한 후, 다른 트랜잭션 B도 동일한 리뷰를 조회합니다.
- 이후 A와 B가 리뷰를 수정하려고 할 때, 데이터가 중간에 변경되었는지 확인합니다.
- 결과
- 만약 B가 A보다 먼저 커밋하고, A가 나중에 커밋을 시도할 때 충돌이 발생하면, A의 트랜잭션이 실패하고 롤백됩니다. 이로써 충돌을 최소화하면서 데이터 일관성을 유지합니다.
명명된 락(Named Lock)
명명된 락은 데이터베이스 자원이 아닌 논리적 이름을 사용해 락을 거는 방식입니다. 보통 응용 프로그램 레벨에서 특정 자원이나 프로세스를 제어할 때 사용됩니다.
- 상황
- 백오피스 관리 시스템에서 특정 보고서 생성 작업은 동시에 한 번만 실행되도록 제한하려고 합니다.
- 동작
- "보고서_생성_작업"이라는 명명된 락을 생성하고, 보고서 생성 트랜잭션이 시작될 때 이 락을 획득합니다.
- 다른 트랜잭션이 동일한 보고서 생성 작업을 시도할 때는 락이 해제될 때까지 대기하게 됩니다.
- 결과
- 한 번에 하나의 보고서 생성 작업만 수행되며, 시스템의 안정성을 유지할 수 있습니다.
분산 락(Distributed Lock)
분산 락은 여러 시스템이나 인스턴스에서 동시에 동일한 자원에 접근할 때, 자원의 일관성을 유지하기 위해 사용되는 락입니다. Redis와 같은 분산 시스템을 사용하여 구현됩니다.
- 상황
- 온라인 예약 시스템에서 여러 서버 인스턴스가 동일한 좌석을 동시에 예약하지 못하도록 하는 상황입니다.
- 동작
- 인스턴스 A가 공연 좌석 10번에 대해 예약을 시도하고, Redis를 사용하여 분산 락을 설정합니다.
- 인스턴스 B도 동일한 좌석 10번을 예약하려고 시도하지만, 인스턴스 A가 락을 걸고 있으므로 예약이 실패하거나 대기 상태가 됩니다.
- 결과
- 인스턴스 A가 예약을 완료하고 락을 해제하면, 인스턴스 B는 다음 예약을 시도할 수 있습니다.
데이터베이스 시스템에서 DB Lock은 데이터의 무결성, 일관성, 그리고 안정성을 보장하기 위한 필수적인 메커니즘입니다. 락의 종류와 각 락이 사용되는 상황을 이해하면, 동시성 문제를 효과적으로 해결하고 데이터베이스 시스템의 성능을 최적화할 수 있습니다.
'Database' 카테고리의 다른 글
[PostgreSQL] PostgreSQL 동시성 관리: 자동 락과 명시적 락의 사용법 (0) | 2024.10.01 |
---|