LostCatBox

Isolation Level 4 And Lock

Word count: 770Reading time: 4 min
2022/12/25 Share

트랙잭션 isolation4단계와 Lock

Created Time: November 27, 2022 9:40 PM
Last Edited Time: December 23, 2022 5:41 PM

왜?

어떤 회사의 과제 구현 도중, 어떻게 멀티 쓰레드 단위 테스트를 통과를 했던 해결과정을 기록하였다.

  • 한 트랜잭션으로 이용하기위해 read와 update를 묶어서 실행하였고, 더티 체킹을 활용하였다.
  • 처음에는 read committed썻고, non-repeatable read현상을 겪어서, 정확한 계산이 나오지 않았다.
  • 격리단계 최대한 올려서 serializable단계로 올리니 DeadLock현상 발생(리드 공유락- 쓰기 베타락 이유)
  • @Lock(LockModeType.*PESSIMISTIC_WRITE*) 을 통해 쓰기 베타락을 사용 → 해당 row는 다른트랙잭션에선 읽기, 쓰기둘다 불가 → 동시성문제 해결완료트랜잭션 isolation level 4단계(INNO DB기준)

트랜잭션이란?

데이터의 정합성을 보장하기위한 기능. 100%적용되거나,아무것도적용되지않아야함. (ACID)(원자성, 일관성, 격리성, 지속성)
→ 이중 격리성(동시에 트랜잭션 처리시)은 ANSI 표준으로 4단계 정의

1

isolation level 4단계

read uncommited

  • Read lock 사용안함
  • 문제점: 더티리드
    트랜잭션에서 처리한 작업(COMMIT/ROLLBACK)이 완료되지 않았음에도 불구하고 다른 트랜잭션에서 볼 수 있게 되는 현상을 더티리드(Dirty Read) 발생

2

read commited

  • 매번 read마다 일관적 읽기를 통한 새로운 snap shot 생성
  • 일반적으로 read lock 설정안함
  • Undo영역존재(변경되기전 레코드 백업영역)

3

  • 문제점: non-repeatable read
    B 트랜잭션이 read를 두번해야하는데 그 중간에 A 트랜잭션이 commit이 일어난다면, 같은 read이지만 다른 결과값도출

repeatable read

  • 일반적으로 read lock 설정안함
  • Undo영역존재(변경되기전 레코드 백업영역)
  • 트랜잭션 번호가 존재하여, 자신보다 이전것만 볼수있다.

4

MVCC(Multi Version Concurrency Control) - 잠금을 사용하지 않는 일관된 읽기를 제공

MVCC는 다중 버전 병행수행 제어의 약자로 DBMS에서는 쓰기(Write) 세션이 읽기(Read) 세션을 블로킹하지 않고, 읽기 세션이 쓰기 세션을 블로킹하지 않게 서로 다른 세션이 동일한 데이터에 접근했을 때 각 세션마다 스냅샷 이미지를 보장 → INNO DB에서 사용하는 방식이므로, Phantom read 문제점 일어나지 않는다.

InnoDB 스토리지 엔진에서 PHANTOM READ 해결
InnoDB 스토리지 엔진은 레코드 락과 갭 락을 합친 넥스트 키 락을 사용한다. t 테이블에 c1 = 13 , c = 17 인 두 레코드가 있다고 가정하자. 이때 SELECT c1 FROM t WHERE c1 BETWEEN 10 AND 20 FOR UPDATE 쿼리를 수행하면, 10 <= c1 <= 12, 14 <= c1 <= 16, 18 <= c1 <= 20 인 영역은 전부 갭 락에 의해 락이 걸려서 해당 영역에 레코드를 삽입할 수 없다. 또한 c = 13, c = 17인 영역도 레코드 락에 의해 해당 영역에 레코드를 삽입할 수 없다. 참고로 INSERT 외에 UPDATE, DELETE 쿼리도 마찬가지이다.
이러한 방식으로 InnoDB 스토리지 엔진은 넥스트 키 락을 이용하여 PHANTOM READ 문제를 해결한다

  • 문제점: Phantom read
    B트랜잭션이 먼저 시작하여 A트랜잭션이 Insert 하는도중 B 트랜잭션이 두번의 select …for update 쿼리 결과가 서로 다르게된다.(안보였다 보였다함)

    5

참고사항

SELECT .. FOR UPDATE 쿼리는 SELECT하는 레코드에 쓰기 잠금을 걸어야 하는데, 언두 레코드에는 잠금을 걸 수 없습니다.

따라서 위와 같은 쿼리는 언두 영역의 변경 전 데이터를 가져오는 것이 아니라 현재 레코드의 값을 가져오게 됩니다.

serializable

트랜잭션이 완료될 때까지 SELECT 문장이 사용되는 모든 데이터에 Shared Lock이 걸리는 계층

  • 가장 엄격한 격리 수준으로 완벽한 읽기 일관성 모드를 제공
  • 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정 및 입력 불가능
  • 보통 개발시 row를 읽기만 할 때는 REPEATABLE READ
    로, row를 삽입 / 수정 / 삭제할 때는 SERIALIZABLE
    로 isolation level → 설명할줄알기

DB의 lock 종류

Row-level lock

테이블의 row마다 걸리는 row-level lock

  • Shared lock(S lock)은 read에 대한 lock
    이다. 일반적인 SELECT
    쿼리는 lock을 사용하지 않고 DB를 읽어 들인다. 하지만 SELECT ... FOR SHARE
    등 일부 SELECT
    쿼리는 read 작업을 수행할 때 InnoDB가 각 row에 S lock을 건다.
  • Exclusive lock(X lock)은 write에 대한 lock
    이다. SELECT ... FOR UPDATE
    UPDATE
    , DELETE
    등의 수정 쿼리를 날릴 때 각 row에 걸리는 lock이다.
  • 여러 transaction이 동시에 한 row에 S lock을 걸 수 있다. 즉, 여러 transaction이 동시에 한 row를 읽을 수 있다.
  • S lock이 걸려있는 row에 다른 transaction이 X lock을 걸 수 없다. 즉, 다른 transaction이 읽고 있는 row를 수정하거나 삭제할 수 없다.
  • X lock이 걸려있는 row에는 다른 transaction이 S lock과 X lock 둘 다 걸 수 없다. 즉, 다른 transaction이 수정하거나 삭제하고 있는 row는 읽기, 수정, 삭제가 전부 불가능하다.

Record lock

DB의 index record에 걸리는 lock이다.

여기도 row-level lock과 마찬가지로 S lock과 X lock이 있다.

예를 들면, table에서 id를 index로 잡을 경우, where id=10 해당하는 로우는 record lock이 걸린다. 다른 트랜잭션은 Update, Delete, Insert 못함

Gap lock

Gap lock은 DB index record의 gap에 걸리는 lock이다.

여기서 gap이란 index 중 DB에 실제 record가 없는 부분이다.

record lock이 이미 존재하는 row가 변경되지 않도록 보호하는 반면, gap lock은 조건에 해당하는 새로운 row가 추가되는 것을 방지하기 위함이다.

다른 트랜잭션이 범위에 새로운 row 추가 못함

Lock이 해제되는순간은?

lock은 모든 transaction이 commit 되거나 rollback될떄 함께 unlock된다.

CATALOG
  1. 1. 트랙잭션 isolation4단계와 Lock
  2. 2. 왜?
    1. 2.1. 트랜잭션이란?
    2. 2.2. isolation level 4단계
      1. 2.2.1. read uncommited
      2. 2.2.2. read commited
      3. 2.2.3. repeatable read
      4. 2.2.4. serializable
  3. 3. DB의 lock 종류
    1. 3.1. Row-level lock
    2. 3.2. Record lock
    3. 3.3. Gap lock
    4. 3.4. Lock이 해제되는순간은?