본문 바로가기
CS/Database

DB Isolation

by clearinging 2021. 10. 30.
반응형

정의

  • 동시에 여러 transaction을 처리될 때 특정 transaction에서 변경하거나 조회할 수 있도록 허용하는 level

종류

  • Read Uncommitted
  • Read Commited
  • Repeatable Read
  • Serializable

특징

  • 격리 수준이 높아질 수록 성능이 떨어집니다
  • 트랜젝션을 순서대로 실행하면 문제가 생기지 않지만 성능 이슈로 하위 level의 격리 수준을 사용하고 있습니다.
  • 잠금 시간을 최소화 하는 방식을 체택하는 것을 추천 -> 성능이슈가 발생

Transaction race codition으로 발생하는 문제들

종류

  • dirty read/write
  • Non-repeatable read/Read skew
  • 변경 유실
  • 한 transaction의 결과가 다른 transaction의 쿼리에 영향을 주는 경우
  • Phantom Read

dirty read/write

dirty read

  • dirty read 정의: 다른 transaction에 전체 insert/update가 commit되어 모두 DB에 반영이 되지 않은 상태에서 데이터를 읽어 올때 발생하는 이슈

dirty wrtie

  • dirty write 정의 : commit 되지 않는 레코드를 덮어 씌울때 발생하는 이슈
  • 이미 다른 user가 변경한 값을 다시 덮어 씌워서 발생하는 이슈

Non-repeatable read/Read skew

read skew

  • 정의 : transaction에서 읽는 시점에 따라서 데이터가 내부 데이터가 변하는 이슈
  • read transaction이 실행하는 동안 읽은 데이터가 변경되면 현재 값과 조회된 값이 다른 결과가 나오게 되는 이슈입니다.

변경 유실

  • 정의: 같은 데이터를 update 쿼리로 수정할 때 발생
  • count 증가와 google 독스에 정보를 수정하는 것과 같은 wiki 페이지를 수정할 때 발생할 수 있습니다.
  • 예시에서 처음 읽을 때 count 값이 1이고, update 쿼리를 위해 count + 1을 해서 2를 update query를 넣어서 반영을 합니다. -> 하지만 다른 transaction이 이미 2로 업데이트 했기 때문에 3으로 변경해야하지만 2로 update해서 이슈가 발생(앞에 update 쿼리가 무시되는 이슈)
  • 대처 방식
    • DB가 원자적인 연산을 실행: update article set readcnt = readcnt + 1 where id = 1; 과같이 수정
    • select ... for update 기능 사용 : for update할 경우 select할때 부터 x lock이 걸려 다른 trnansaction이 읽지를 못해서 동시성 제어 가능(commit/rollback이 발생할 때 lock이 풀림)
    • 낙관적 lock/CAS: table 에 version이라는 column을 추가하고 update 쿼리가 발생할 경우 version + 1을 해줍니다. 그리고 where 절에 version이 같을 경우에만 update 쿼리 발생 -> version이 다르면 update 실패로 간주하는 방법

한 transaction의 결과가 다른 transaction의 쿼리에 영향을 주는 경우

  • 정의 : 다른 record를 update하지만 비즈니스 로직이 깨지는 현상
  • 예시 : 하루에 duty가 true인 사람은 무조건 1명 이상이어야 할 경우 2명이 동시에 duty를 false로 수정할 때 발생 -> 동시성 문제로 조회할 때는 duty true가 2명었지만 서로 다른 record를 false로 update해서 duty가 true인 사람이 1명 이상인 비즈니스 로직이 깨지는 이슈

Phantom Read(유령 읽기)

Phantom Read

  • 정의 : 한 transaction에 내에서 같은 쿼리를 두번 수행했을 때 새로운 row 가 추가되는 것을 의미 -> 유령 레코드라고 말한다.

격리 level

Read Uncommitted

  • dirty read/write를 포함한 모든 이슈가 발생

Read Committed

  • 정의 commit된 데이터만 읽을 수 있음 -> commit 된값과 transaction이 진행하고 있는 레코드를 lock을 걸어서 관리
  • commit 된 데이터만 덮어 쓰기 가능
    • row 단위 lock만 가능
    • 이미 다른 transaction이 수정을 하고 있을 경우 commit이 완료될 때끼지 대기
  • 발생 이슈: dirty read/write를 재외한 이슈가 발생

Repeatable Read

  • 정의 : 하나의 transaction 동안 같은 데이터를 읽게 하는기능
  • MVCC(Multi-Cersion Concurrency Control) : 읽는 사람 마다 version을 명시해서 현재 자신의 버전정보를 가져오는 기능
  • 발생이슈: 변경 유실, 다른 transaction에 영향을 주는 이슈 발생

Serializable

  • insert/select/create table as select .. etc등은 다른 isloation 에서는 lock을 걸지 않고 사용합니다.
  • 하지만 serializable에서는 모두 shared lock을 걸어서 사용하기때문에 성능상에 이슈가 발생합니다
  • 이슈가 발생하지 않지만 성능 이슈가 너무 많이 발생해서 현업에서 잘 사용하지 않습니다.

Summary

Dirty read/write read skew phantom read 변경유실
read uncommited o o o o
read commited x o o o
repeatable read x x o o
serializable x x x x

참고 사이트

반응형

'CS > Database' 카테고리의 다른 글

RDB Join 방식  (0) 2021.12.09
NamingLock을 이용한 동시성 이슈, Deadlock query 이슈 해결  (0) 2021.12.01
Mysql Replication  (3) 2021.10.06
DB 스키마  (0) 2021.06.05
RDB Join Query  (0) 2021.06.05