서은파파의 추월차선

데이터베이스 락(Lock)에 대해서 본문

DB

데이터베이스 락(Lock)에 대해서

seoeunpapa 2025. 1. 14. 00:02
728x90

 

데이터베이스의 **락(Lock)**은 여러 사용자 또는 프로세스가 동시에 동일한 데이터에 접근하려고 할 때 데이터의 무결성과 일관성을 보장하기 위해 사용됩니다.


1. 락의 주요 종류

1.1. 공유 락(Shared Lock, S Lock)

  • 특징: 데이터 읽기를 허용하지만, 쓰기를 막습니다.
  • 사용 사례: 여러 트랜잭션이 동시에 데이터를 읽을 수 있지만, 쓰기 작업은 불가능.
  • 예시:
    • 트랜잭션 A가 SELECT ... FOR SHARE를 실행하면, 트랜잭션 B는 읽기를 허용하지만 쓰기는 불가능.
-- 공유 락 예시
START TRANSACTION;
SELECT * FROM orders WHERE id = 1 FOR SHARE;
-- 이 상태에서 다른 트랜잭션은 읽을 수 있지만, 쓰기는 불가능

1.2. 배타 락(Exclusive Lock, X Lock)

  • 특징: 데이터 읽기와 쓰기 모두 다른 트랜잭션에서 접근 불가능.
  • 사용 사례: 데이터 수정 작업이 진행 중일 때, 다른 작업을 막음.
  • 예시:
    • 트랜잭션 A가 UPDATE를 수행하면 해당 레코드에 배타 락이 걸림.
-- 배타 락 예시
START TRANSACTION;
UPDATE orders SET status = 'Shipped' WHERE id = 1;
-- 트랜잭션이 완료될 때까지 다른 트랜잭션은 해당 레코드에 접근 불가능

1.3. 행 락(Row Lock)

  • 특징: 특정 행에만 락을 걸어 다른 행에 대한 접근은 허용.
  • 사용 사례: 테이블의 일부 데이터만 수정하는 경우.
  • 예시:
    • 특정 행만 잠금 처리하여 효율적으로 동시성 제어.
-- 행 락 예시
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
-- id가 1인 행만 잠김, 나머지 행은 접근 가능

1.4. 테이블 락(Table Lock)

  • 특징: 테이블 전체에 락을 걸어 데이터 수정 및 읽기 제어.
  • 사용 사례: 대량 데이터 변경 작업.
  • 예시:
-- 테이블 락 예시
LOCK TABLE orders IN EXCLUSIVE MODE;
-- orders 테이블 전체에 대한 읽기 및 쓰기 제한

1.5. 의도 락(Intent Lock)

  • 특징: 테이블이나 행 수준에서 락을 걸기 전에 의도를 나타냅니다.
  • 종류:
    • 의도 공유 락(Intent Shared Lock, IS): 특정 행에 공유 락을 걸 예정임을 나타냄.
    • 의도 배타 락(Intent Exclusive Lock, IX): 특정 행에 배타 락을 걸 예정임을 나타냄.
  • 사용 이유: 데이터베이스가 락 충돌을 더 효율적으로 탐지.

2. 락 충돌과 대기

락 충돌은 두 개 이상의 트랜잭션이 동일한 데이터에 대해 상충되는 락을 요구할 때 발생합니다.

예시: 충돌 상황

  1. 트랜잭션 A가 행에 배타 락을 겁니다.
  2. 트랜잭션 B가 동일한 행에 공유 락을 요청합니다.
    • 결과: 트랜잭션 B는 트랜잭션 A가 완료될 때까지 대기.

3. 락 상태 도식화

다음은 락 충돌과 트랜잭션 상태를 도식화한 예입니다.

트랜잭션 A:       START TRANSACTION
                  SELECT * FROM orders WHERE id = 1 FOR UPDATE;

트랜잭션 B:       START TRANSACTION
                  SELECT * FROM orders WHERE id = 1 FOR SHARE;
                  (대기 상태)

4. 성능 최적화를 위한 권장 사항

  1. 락 범위 최소화: 필요한 데이터에만 락을 걸어 동시성을 높입니다.
  2. 트랜잭션 시간 단축: 트랜잭션이 오래 유지되면 락 대기가 길어질 수 있습니다.
  3. 데드락 방지: 트랜잭션 순서를 정해 데드락을 방지합니다.

결론

데이터베이스 락은 동시성을 제어하고 데이터 무결성을 보장하는 데 필수적입니다. 락을 올바르게 이해하고 관리하면 성능과 안정성을 동시에 확보할 수 있습니다.

 


 

위 쿼리는 SQL 표준을 기반으로 작성되었으며, 대부분의 관계형 데이터베이스 관리 시스템(RDBMS)에서 사용 가능합니다. 다만, 특정 락 동작이나 키워드는 데이터베이스 종류에 따라 약간의 차이가 있을 수 있습니다. 아래는 주요 데이터베이스별로 해당 쿼리에 대한 호환성을 간략히 정리한 내용입니다.

 


1. MySQL

  • FOR SHARE: MySQL 8.0 이상에서 지원.
  • FOR UPDATE: MySQL에서 락을 건 행에 대해 배타적 액세스를 제공합니다.
  • 테이블 락: LOCK TABLES 문 사용.
  • 참고: MySQL은 InnoDB 스토리지 엔진에서 행 락을 기본으로 사용하며, 테이블 락은 별도로 요청해야 합니다.

2. PostgreSQL

  • FOR SHARE: PostgreSQL에서는 FOR SHARE를 지원.
  • FOR UPDATE: 행 수준의 배타 락을 제공.
  • 테이블 락: LOCK TABLE 문 사용 가능.
  • 특징: PostgreSQL은 MVCC(Multi-Version Concurrency Control)를 사용하여 읽기 작업과 쓰기 작업 간 충돌을 최소화.

3. Oracle

  • FOR SHARE: Oracle에서는 SELECT ... FOR UPDATE와 비슷한 기능이 있지만 FOR SHARE는 지원하지 않습니다.
  • FOR UPDATE: 행 수준의 락을 제공합니다.
  • 테이블 락: LOCK TABLE 문을 사용.
  • 참고: Oracle은 자동 락 관리를 통해 데이터 무결성을 유지합니다.

4. SQL Server

  • FOR SHARE: SQL Server에서는 WITH (NOLOCK)이나 WITH (UPDLOCK) 등의 힌트로 비슷한 기능 구현 가능.
  • FOR UPDATE: SQL Server에서는 명시적으로 FOR UPDATE를 제공하지 않지만, 업데이트 문 자체가 배타 락을 발생시킵니다.
  • 테이블 락: TABLOCK 또는 TABLOCKX 힌트를 사용하여 구현.

요약

  • MySQLPostgreSQL에서는 위 쿼리가 대부분 그대로 동작.
  • OracleSQL Server에서는 약간의 구문 차이나 동작 방식 차이가 있으니, 환경에 맞춰 쿼리를 조정해야 합니다.
728x90