관리 메뉴

공부한것들을 정리하는 블로그 입니다.

@Transactional isolation 본문

Spring/공부

@Transactional isolation

호 두 2022. 10. 27. 16:52
반응형


2. isolation
트랜잭션 격리 수준. 트랜잭션이 다른 트랜잭션과 격리되어야 하는 수준을 결정한다.

- 트랜잭션이란, 
트랜잭션이란, 데이터베이스의 데이터를 조작하는 작업의 단위(unit of work)이다.
트랜잭션은 흔히 이론적으로 ACID 원칙을 보장해야 한다고 한다. 
하지만, 실제로는 ACID 원칙은 종종 지켜지지 않는다. 왜냐하면 ACID 원칙을 strict 하게 지키려면 동시성이 매우 떨어지기 때문이다.

그렇기 때문에 DB 엔진은 ACID 원칙을 희생하여 동시성을 얻을 수 있는 방법을 제공한다. 바로 트랜잭션의 isolation level이다.
isolation이 낮을수록 ACID 원칙이 지켜지지 않기에(격리성이 낮음) 문제가 생길 수 있지만, 대신 더 높은 동시성을 얻을 수 있다.

데이터베이스에서 트랜잭션이 독립적인 수행을 하도록 하기 위해서, isolation level에 따라 서로 다른 Locking을 사용한다.
isolation level이 높아질수록 더 많이, 더 빡빡하게 lock을 거는 것이다.

따라서, isolation level 별 locking 전략을 이해하기 위해, 먼저 필수적인 Lock들에 대한 개념들을 먼저 정리하고 넘어간다.



- MYSQL의 innoDB의 lock

- Lock : 트랜잭션 처리의 순차성을 보장하기 위한 방법이다.(동시성 제어)
  - Locking으로 동시에 수행되는 수많은 트랜잭션들을 순서대로 처리하는 방식으로 구현하게 되면, 데이터베이스의 성능은 떨어지게 된다. 
  - 성능을 높이기 위해 Locking의 범위를 줄인다면, 잘못된 값이 처리될 문제가 발생할 수 있다.

- Row-level lock
  - shared lock (S lock)
    - 공유 락. read a row
    - 데이터를 읽을 때 사용되어지는 lock
    - 일반적인 SELECT 쿼리는 lock을 사용하지 않고 DB를 읽어 들인다. 
      - 하지만 SELECT ... FOR SHARE 등 일부 SELECT 쿼리는 read 작업을 수행할 때 InnoDB가 각 row에 S lock을 건다.
    - 여러 transaction이 동시에 한 row에 S lock을 걸 수 있다.
      - 즉, 여러 transaction이 동시에 한 row를 읽을 수 있다.
    - S lock이 걸려있는 row에 다른 transaction이 X lock을 걸 수 없다.
      - 즉, 다른 transaction이 읽고 있는 row를 수정하거나 삭제할 수 없다.

  - Exclusive lock (X lock)
    - 배타 락. update or delete a row
    - 데이터를 변경하고자 할 때 사용되며, 트랜잭션이 완료될 때까지 유지된다.
    - SELECT ... FOR UPDATE나 UPDATE, DELETE 등의 수정 쿼리를 날릴 때 각 row에 걸리는 lock이다.
    - X lock이 걸려있는 row에는 다른 transaction이 S lock과 X lock 둘 다 걸 수 없다.
      - 즉, 다른 transaction이 수정하거나 삭제하고 있는 row는 읽기, 수정, 삭제가 전부 불가능하다.


- Record lock
  - Record lock은 row가 아니라 DB의 개별 index record에 걸리는 lock이다.
  - 여기도 row-level lock과 마찬가지로 S lock과 X lock이 있다.
  - 테이블에 인덱스가 생성되어 있지 않더라도 테이블 생성시에 함께 생성되는 default Clustered Index의 레코드에 Lock을 걸어, 항상 인덱스 레코드에 Lock을 설정한다.
    - ex) 트랜잭션 A가 테이블에 대해 id=1 조건으로 조회중일 경우, 트랜잭션 B의 id=1 Update/Delete 접근을 막는다.
  
- Gap lock
  - Gap lock은 DB index record의 gap에 걸리는 lock이다.
    - ex) index가 id인 table에서 id=3, id=10인 row가 2개 있으면, gap=4~9이다.
  - Gap lock은 해당 gap에 접근하려는 다른 쿼리의 접근을 막는다.
    - Record lock이 해당 index를 타려는 다른 쿼리의 접근을 막는 것과 동일하다.
    - record lock이 이미 존재하는 row가 변경되지 않도록 보호하는 반면, gap lock은 조건에 해당하는 새로운 row가 추가되는 것을 방지하기 위함
    - ex) between 3 and 10으로 조회중이면, 2~11을 입력하는 것을 lock.
      - phantom row 현상을 막는 것이 목적이므로, 최초 레코드의 이전 gap + 마지막 레코드의 이후의 gap 에도 lock을 설정한다.

- next-key lock
  - gap lock + record lock의 조합으로 만들어진다.
    - ex) index가 id인 table에서 id=3, id=10인 row가 2개 있으면, next-key lock은 2~11에 걸린다.
  

* Dirty Read : 변경 후 아직 commit 되지 않은 값을 읽고, Rollback 된 후의 값을 다시 읽어 최종 결과 값이 상이한 현상
* Non-Repeatable Read : 한 트랜잭션 내에서 같은 쿼리를 두번 수행할 때, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써 두 쿼리가 상이하게 나타나는, 비 일관성의 발생을 의미한다.
* phantom row
Phantom Row의 "Phatom"은 유령이라는 뜻으로, 트랜잭션 A가 수행중 다른 트랜잭션 B가 생성한 Row가 갑자기 나타나는 것을 말한다


isolation 종류
* isolation level이 낮을수록 ACID 원칙이 지켜지지 않기에(격리성이 낮음) 문제가 생길 수 있지만, 대신 더 높은 동시성을 얻을 수 있다.

* '동시성 제어'란 동시에 실행되는 트랜잭션의 수를 최대화 하는 것과 데이터 CRUD 시 데이터의 무결성을 유지하는 것을 이야기합니다.



  - DEFAULT

    - 데이터 소스의 기본 격리 수준

    - Oracle 은 (level 1) READ_COMMITED

    - Mysql InnoDB 는 (level 2) REPEATABLE_READ
  - 0 : READ_UNCOMMITTED
    - Dirty Read, Non-Repeatable Read 및 Phantom Read가 발생할 수 있음을 나타낸다.
    - 다른 트랜잭션의 커밋되지 않은 데이터도 읽을 수 있음.
  - 1 : READ_COMMITTED
    - Dirty Read를 방지하고 반복할 수 없으며 Phantom Read가 발생할 수 있음을 나타낸다.
    - 커밋된 데이터만 읽음. 반복조회시 커밋 시점에 따라 데이터 상이.
  - 2 : REPEATABLE_READ
    - Dirty Read와 Non-Repeatable Read가 방지되지만 Phantom Read가 발생할 수 있음을 나타낸다.
    - 반복적으로 조회하여도 동일한 데이터를 보장.
  - 3 : SERIALIZABLE
    - Dirty Read와 Non-Repeatable Read, Phantom Read가 방지될 수 있음을 나타낸다.
    - 데이터 처리의 직렬화를 보장.
    - 데이터베이스에서 거의 사용되지 않음


반응형
Comments