[Database] 트랜잭션의 격리수준

SeongWon Oh·2021년 10월 9일
0

Database

목록 보기
4/4
post-thumbnail

트랜잭션의 격리수준(Isolation)이란?

트랜잭션의 격리 수준이란 동시에 여러 트랜잭션이 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터들을 볼 수 있도록 허용할지 말지를 결정하는 것이다.


트랜잭션의 격리수준의 종류

READ_UNCOMMITTED (level 0)

  • 각 트랜잭션에서의 변경 내용이 Commit, Rollback여부에 상관없이 다른 트랜잭션에서 읽을 수 있는 상태로 정합성 문제가 많은 격리수준이기에 사용하지 않는 것을 권장한다.
  • 트랜잭션이 작업을 완료하지 않았는데 다른 트랜잭션에서 값을 볼 수 있는 Dirty Read현상이 발생한다.

READ_COMMITTED (level 1)

  • READ_UNCOMMITED의 dirty read의 문제를 없애며 개선한 것이 READ_COMMITED이다.
  • READ_UNCOMMITED처럼 실제 테이블의 값을 가져오는 것이 아닌 undo영역에 백업되어 있는 레코드에서 값을 가져온다.
  • 즉, 트랜잭션들은 커밋된 값들만 가져오는 것이다.
  • 위의 사진과 같이 transaction1에서 table의 id가 2인 값을 2로 업데이트 하였고 그 이후에 Transaction2에서 2번을 읽었지만 실제로 transaction2에서 받는 값은 백업 영역에 업데이트 되기 이전의 레코드인 마늘을 return하는 것을 확인할 수 있다.
- 하지만 READ_COMMITED에는 위와 같은 문제점이 존재한다. 이전 사진 이후로 Transaction1이 커밋을 하면 Table의 id=2의 값은 고기로 커밋되게된다. 그 후에 Transaction2에서 똑같이 id=2번 레코드를 읽게되면 첫번째 읽은 마늘과 다르게 고기라는 값을 받는 Reapeatable Read의 정합성에 어긋난다.

Non-Repeatable Read

  • 한 트랜잭션에서 같은 쿼리를 두번 실행했을 때 발생할 수 있는 데이터의 불일치이다.
  • 트랜잭션 A가 어떤 값 1을 읽어뒀다. 이후에 A는 같은 쿼리를 실행하여 같은 레코드를 다시 읽어오려 하는데 그 사이에 트랜잭션 B가 1을 2로 변경한 후 커밋해버리면 A가 같은 쿼리를 실행하였음에도 다른 결과를 불러오게 된다.

REPEATABLE_READ (level 2)

  • MySql을 예시로 들면 트랜잭션마다 ID를 부여하고 각각의 트랜잭션은 자신의 ID보다 작은 트랜잭션에서 변경한 것만 읽게 하고 있다.
  • 즉, Undo공간에 데이터를 백업을 해두고 실제 레코드 값을 변경하며, 트랜잭션마다 ID에 따라 읽어오는 값들을 다르게 하는 방법이다.
  • 이때 백업된 데이터는 불필요하다고 판단되는 시점에 주기적으로 삭제하지만 Undo에 백업된 데이터가 많아지면 SQL의 처리 성능이 떨어질 수 있다.
  • 하지만 REAPEATABLE READ는 Phantom read의 문제가 발생할 수 있다.

Phantom Read

  • 한 트랜잭션에서 일정 범위의 레코드를 두번 이상 읽을 때, 첫 번재 쿼리에서 없던 유령 레코드가 두번째 쿼리에서 나타나는 현상을 말한다
  • 트랜잭션 A가 어떠한 쿼리를 사용하여 특정 범위의 값들인 [1,2,3,4]를 읽어왔다. 이후 똑같은 쿼리를 실행하려 하는데 트랜잭션 B가 [5,6,7]을 테이블에 추가하면 A가 같은 쿼리를 실행하였음에도 다른 결과(처음에 없던 데이터들이 생김)를 불러오게 된다.

SERIALIZABLE (level 3)

  • 가장 단순하면서 엄격한 격리수준으로 쓰기 잠금을 하는 방법이다.
  • Commit이 일어나지 않은 트랜잭션이 사용중인 데이터에 접근하려는 트랜잭션은 Lock을 걸어 waiting을 하고 commit이 실행되어야지만 추가적인 logic을 진행한다.
  • SERIALIZABLE은 트랜잭션이 waiting을 하게되어 성능상에 문제가 발생한다.
  • Phantom read가 발생하지 않지만 성능상의 문제로 데이터베이스에서 거의 사용하지 않는다.

📝 한줄 정리

READ_UNCOMMITTED는 데이터 정확성의 문제를 갖고있고, REPEATABLE_READ는 성능상의 문제가 있어 보통 READ_COMMITTED와 REPEATABLE_READ를 많이 이용한다.


Reference

profile
블로그 이전했습니다. -> https://seongwon.dev/

0개의 댓글