[데이터베이스] 잠금(lock)

서유진·2022년 9월 23일
1

기술이 술술

목록 보기
1/5
post-thumbnail

잠금이란??

트랜잭션 처리의 순차성을 보장하기 위한 방법

http://wiki.gurubee.net/pages/viewpage.action?pageId=26745044

공유 잠금(Shared lock)

  • 데이터를 읽을 때 사용하는 Read Lock과 같은 개념
  • 공유 잠금 끼리는 충돌이 없음
  • 읽는 작업들이 동시에 자원에 접근해도 문제가 발생하지 않기 때문
    베타 잠금이 걸린 상태, 즉 쓰기 중이라면 읽지 못함
    (공유 잠금을 걸지 못함)

베타 잠금(Exclusive lock)

  • 데이터를 쓸 때 사용하는 Write Lock과 같은 개념
  • 공유 잠금과 베타 잠금 모두에게 충돌이 발생
    읽는 중에 쓰기 불가, 쓰는 중에 쓰기 불가
  • 따라서 베타 잠금이 해제될 때 까지 SELECT를 포함해서 자원에 접근이 불가능함

블로킹 (Blocking)

  • Lock경합이 발생해 특정 세션이 작업을 진행하지 못하고 멈춰 선 상태
  • 공유 잠금 - 베타 잠금 , 베타 잠금 - 베타 잠금
  • 먼저 진행된 트랜잭션이 COMMIT 되거나 ROLLBACK되어야 진행이 가능

블로킹을 최소화하려면??

  • 트랜잭션을 가능한 짧게 !!!
  • 동일한 데이터를 변경하는 트랜잭션이 동시에 수행되지 않도록 해야 한다.
  • 트랜잭션 격리성 수준을 불필요하게 상향 조정하지 않는다.
  • 쿼리를 오랜시간 잡아두지 않도록 적절한 튜닝(리팩토링?)을 진행한다.
  • lock_timeout을 설정하여 해당 잠금의 최대 시간을 설정한다.

lock_timeout
동시 접근을 막기위해 고의적으로 테이블에 잠금을 걸었을 때,
뒤이어 해당테이블에 접근하는 세션이 좀 더 대기해주길 원할때 사용

🔍 잠금 제한 시간 설정은 세션별로 적용되기 때문에, 새로운 세션으로 접속 시에는 다시 설정을 해야 한다.


교착상태(DeadLock)

  • 교착상태는 여러 개의 트랜잭션(Transaction)들이 실행을 하지 못하고 서로 무한정 기다리는 상태
  • 블로킹을 두 트랜잭션이 서로간에 걸린 교착상태 라고 표현

    블로킹과 교착상태의 차이
    일반적인 블로킹은 언젠가는(블로킹한 트랜잭션이 끝나면) 사라지게 된다.
    하지만 교착상태는 서로가 서로에게 블로킹을 걸었기 때문에 상대 트랜잭션이 끝나기만을 서로 기다리며 블로킹이 계속되기 때문에 끝나지 않는다.

Transaction 1> start transaction; insert into B values(1);  # lock (B)
Transaction 2> start transaction; insert into A values(1);  # lock (A)

Transaction 1> insert into A values(1); 	# lock(A)에 접근
Transaction 2> insert into B values(1);		# lock(B)에 접근

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

교착상태를 해결하려면??

  • 예방 기법
    • 각 트랜잭션이 실행되기 전에 필요한 모든 자원을 Lock(잠금)한다.
    • SET LOCK_TIMEOUT문을 통해 일정 시간이 지나면 쿼리를 취소한다
  • 회피 기법
    자원을 할당할 때 시간 스탬프(Time Stamp)를 활용해서 교착상태가 일어나지 않도록 회피하는 방법
    • Wait-Die 방식
    • Wound-Wait 방식
  • 낙관적 병행 제어 기법
    트랜잭션이 실행되는 동안에는 검사를 수행하지 않고, 트랜잭션이 커밋된 후에 데이터에 문제가 있다면 롤백(Rollback)하는 방법
  • 빈도 줄이기 기법
    • 트랜잭션은 최대한 짧게 해서 블로킹 시간을 최소화해야 합니다.
    • 처리하는 오브젝트 순서를 같게 한다.
    • 읽기 잠금 (SELECT ~ FOR UPDATE)의 사용을 피한다.
    • 테이블 단위의 Lock(잠금)을 획득해 갱신을 직렬화한다.
    • Index 설계
    • Isolation level(고립 수준)을 조정

(+) 비관적 락과 낙관적 락

비관적 락(pessimistic lock)

  • 충돌이 일어날 것이라고 가정하고 시작
  • 트랜잭션에서 변경하려는 레코드에 대해 락(Shared Lock 또는 Exclusive Lock)을 획득하고 쿼리를 수행하는 방식
  • Reeatable Read 또는 Serializable 정도의 격리성 수준에서 가능 격리성 알아보기
  • 충돌이 많이 발생하는 경우에 사용
  • 공유잠금(Shared lock), 베타잠금(Exclusive lock) 전부 일어날 수 있음

낙관적 락(optimistic lock)

  • 충돌이 일어나지 않을 것이라고 가정하고 시작
  • 트랜잭션에서 락 없이 일단 쿼리 수행을 하고 마칠 때 서로 다른 트랜잭션에서 충돌이 있었는지 확인하고 문제가 있으면 충돌이 난 트랜잭션을 롤백하는 방식
  • DB에서 제공해주는 특징을 이용하는 것이 아닌 Application Level에서 잡아주는 Lock
  • 충돌이 적게 발생하는 경우에 사용
  • 공유잠금(Shared lock), 베타잠금(Exclusive lock) 전부 일어날 수 있음
profile
Backend Dev.

0개의 댓글