ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DB - 블로킹(Blocking)과 데드 락(Deadlock)
    DB 2024. 11. 11. 22:27

    블로킹(Blocking)

    정의:

    • 한 트랜잭션이 자원(테이블, 행 등)을 Lock 하고 있을 때, 다른 트랜잭션이 해당 자원에 접근하지 못하고 기다리는 현상

    특징:

    • 일시적인 현상으로, Lock 이 해제되면 자연스럽게 해결됨
    • 정상적인 데이터베이스 동작의 일부
    • 데이터 일관성을 보장하기 위한 매커니즘

    예시 코드)

    -- 블로킹 예시
    
    -- 트랜잭션 1
    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    -- 여기서 잠시 멈춤 (아직 COMMIT하지 않음)
    
    -- 트랜잭션 2 (동시 실행)
    BEGIN;
    UPDATE accounts SET balance = balance + 50 WHERE id = 1;  
    -- 트랜잭션 1이 COMMIT할 때까지 대기 (블로킹)

     

    데드 락(Deadlock)

    정의:

    • 두 개 이상의 트랜잭션이 각각의 자원을 점유한 상태에서 상대방의 자원을 요청하며 무한히 기다리는 상태

    특징:

    • 자연스럽게 해결되지 않음
    • 시스템의 개입이 필요함
    • 순환 대기가 발생

    발생조건

    1. 상호 배제(Mutual Exclusion)
      • 자원은 한 번에 하나의 트랜잭션만 사용 가능
      • 다른 트랜잭션은 해당 자원 사용 불가
    2. 점유와 대기(Hold and Wait)
      • 트랜잭션이 최소한 하나의 자원을 보유
      • 다른 트랜잭션이 사용 중인 자원을 추가로 요청
    3. 비선점(No Preemption)
      • 이미 할당된 자원을 강제로 빼앗을 수 없음
      • 자원을 가진 트랜잭션이 자발적으로 해제하기 전까지 계속 사용
    4. 순환 대기(Circular Wait)
      • 트랜잭션들이 순환 형태로 자원을 요청
      • 각 트랜잭션은 다음 트랜잭션이 가진 자원을 요청

    예시 코드)

    -- 데드락 예시
    
    -- 트랜잭션 1
    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    -- 여기서 id=2인 레코드의 락을 기다림
    UPDATE accounts SET balance = balance + 100 WHERE id = 2;
    
    -- 트랜잭션 2 (동시 실행)
    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE id = 2;
    -- 여기서 id=1인 레코드의 락을 기다림
    UPDATE accounts SET balance = balance + 100 WHERE id = 1;

     

    데드락 해결 방안

      1. 예방(Prevention)

    -- 1. 순서 기반 접근
    BEGIN;
    SELECT * FROM accounts 
    WHERE id IN (1, 2) 
    ORDER BY id FOR UPDATE;  -- 항상 작은 ID부터 잠금
    
    -- 2. 한 번에 모든 자원 획득
    BEGIN;
    SELECT * FROM accounts 
    WHERE id IN (1, 2, 3) FOR UPDATE;


      2. 회피(Avoidance)

    -- 타임아웃 설정
    SET innodb_lock_wait_timeout = 50;  -- 50초 후 타임아웃
    
    -- 트랜잭션 격리 수준 조정
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

     

      3. 감지 및 복구(Detection & Recovery)

    -- 데드락 정보 확인
    SHOW ENGINE INNODB STATUS;
    
    -- 데드락 발생 시 자동으로 롤백되는 트랜잭션 처리
    BEGIN;
    DECLARE EXIT HANDLER FOR DEADLOCK
    BEGIN
        ROLLBACK;
        -- 재시도 로직
    END;

     

     

    데드락 방지를 위한 Best Practices

    1. 애플리케이션 레벨
      1. 트랜잭션 범위를 최소화
      2. 일관된 순서로 데이터 접근
      3. 대량 처리 시 배치 처리 활용
      4. 적절한 인덱스 설계
    2. 데이터베이스 레벨
      1. 적절한 격리 수준 설정
      2. 인덱스 최적화
      3. 주기적인 모니터링
      4. 타임아웃 설정
    3. 운영관리
      1. 데드락 로그 모니터링
      2. 성능 지표 관리
      3. 주기적인 테이블 유지보수

     

    결론

    블로킹과 데드락은 모두 동시성 제어 과정에서 발생하는 현상이지만, 블로킹은 정상적인 동작의 일부로 볼 수 있는 반면, 데드락은 비정상적인 상황으로 보고 적극적인 방지가 필요하다. 효과적인 데이터베이스 설계와 모니터링을 통해 두 현상 모두 최소화할 수 있다.

    특히 실제 운영환경에서는 데드락 발생 시 자동으로 재시도하는 로직을 구현하는 것이 중요하다.

     

    서버측에서 재시도 관련 처리를 테스트를 진행한 코드를 다음 링크에서 확인 가능

    https://github.com/O-Seonsik/lock-test/tree/master/src/modules/products

Designed by Tistory.