모르지 않다는 것은 아는것과 다르다.

Database

트랜잭션 격리수준(Isolation level)

채마스 2022. 2. 27. 02:03

트랜잭션 격리수준

  • 동시에 여러 트랜잭션이 처리되는 상황에서 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있도록 허용할지 말지를 결정하는 것을 말한다.
  • ACID
    • 원자성(Atomicity) : 트랜잭션은 모두 실행되거나 아예 실행되어서는 안된다. 성공적인 트랜잭션은 commit 하고 실패한 트랜잭션은 rollback 한다.
    • 일관성(Consistency) : 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지되어야 한다. 각 트랜잭션은 일관성을 보장하도록 프로그램을 작성해야 한다.
    • 격리성/독립성(Isolation) : 하나의 트랜잭션이 데이터를 갱신하는 동안 이 트랜잭션이 완료되기 전에 갱신중인 데이터에 다른 트랜잭션에 영향을 주지 않아야 한다.
    • 지속성(Durability) : 트랜잭션이 완료된 이후의 상태는 데이터베이스에 영구적으로 반영되어야 하며, 비록 시스템이 실패하여도 그 상태가 일관되게 유지되어야 한다.






격리성 관련 문제

아래의 내용은 트랜잭션 격리성에 따라 발생할 수 있는 문제들이다.

 

  • Dirty Read

 

  • 한 트랜잭션(Transaction A)이 데이터에 접근하여 값을 'x'에서 'y'로 변경했고 아직 커밋을 하지 않았을때, 다른 트랜잭션(Transaction B)이 해당 데이타를 Read 하면 문제가 발생할 수 있다.
  • 트랜잭션 A가 변경값을 커밋하지않고 다시 롤백한다면, 트랜잭션 B는 롤백되지 않은 데이터 'y' 를 가져갈 수 있기 때문이다.



  • Non-Repeatable Read

 

  • 한 트랜잭션(Transaction A)이 데이터를 Read 하고 있다. 이때 다른 트랜잭션(Transaction B)가 데이터에 접근하여 값을 변경 또는 삭제하고 커밋하면 문제가 발생할 수 있다.
  • 그 후 Transaction A는 다시 해당 데이터를 Read하고자 하면 변경된 데이터 혹은 사라진 데이터를 찾게 된다.



  • Phantom Read
    • Transaction A가 특정 조건으로 데이터를 검색하여 결과를 얻었다.
    • 이때 Transaction B가 접근해 해당 조건의 데이터 일부를 삭제 또는 추가했을때, 아직 끝나지 않은 Transaction A이 다시 한번 해당 조건으로 데이터를 조회 하면 Transaction B에서 추가/삭제된 데이터가 함께 조회/누락 된다.






트랙잭션 격리수준 (Isolation level)

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

 

READ UNCOMMITTED





  • 각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관 없이 다른 트랜잭션에서 값을 읽을 수 있다.
  • 동시 처리 성능은 가장 높다.
  • 하지만 정합성에 문제가 많은 격리 수준이기 때문에 사용하지 않는 것을 권장한다.
  • 아래의 그림과 같이 Commit이 되지 않는 상태지만 Update된 값을 다른 트랜잭션에서 읽을 수 있다.
  • 발생할 수 있는 문제점 : Dirty Read, Non-Repeatable Read, Phantom Read





READ COMMITTED



  • 커밋이 완료된 데이터만 읽을 수 있다.
  • RDB에서 대부분 기본적으로 사용되고 있는 격리 수준이다. -> 보통 Read Committed를 디폴트 수준으로 지정한다.
  • Dirty Read와 같은 현상은 발생하지 않는다.
  • Dirty Read가 발생할 여지는 없으나, Read Uncommitted 수준보다 동시 처리 성능은 떨어진다.
  • 실제 테이블 값을 가져오는 것이 아니라 Undo 영역에 백업된 레코드에서 값을 가져온다. -> 커밋되기전 데이터를 가져온다.
  • 트랜잭션-1이 Commit한 이후 아직 끝나지 않는 트랜잭션-2가 다시 테이블 값을 읽으면 값이 변경됨을 알 수 있다.
  • 하나의 트랜잭션내에서 똑같은 SELECT 쿼리를 실행했을 때는 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋난다.
  • 이러한 문제는 주로 입금, 출금 처리가 진행되는 금전적인 처리에서 주로 발생한다. -> 데이터의 정합성은 깨지고, 버그는 찾기 어려워 진다.
  • 발생할 수 있는 문제점 : Non-Repeatable Read, Phantom Read





Repeatable Read



  • 트랜잭션 내에서 한번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회 된다.
  • 이는 개별 데이타 이슈인 Dirty Read나 Non-Repeatable Read는 발생하지 않지만, 결과 집합 자체가 달라지는 Phantom Read는 발생가능하다.
  • MySQL에서는 트랜잭션마다 트랜잭션 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션 번호에서 변경한 것만 읽게 된다.
  • Undo 공간에 백업해두고 실제 레코드 값을 변경한다.
    • 백업된 데이터는 불필요하다고 판단하는 시점에 주기적으로 삭제한다.
    • Undo에 백업된 레코드가 많아지면 MySQL 서버의 처리 성능이 떨어질 수 있다.
  • 이러한 변경방식은 MVCC(Multi Version Concurrency Control)라고 부른다.
  • 발생 문제점 : Phantom Read





Serializable

  • 가장 엄격한 격리 수준
  • Dirty Read, Non-Repeatable Read, Phantom Read 문제가 모두 해결된다.
  • 하지만 성능이 급격히 떨어질 수 있다.
  • 데이터베이스에서 거의 사용되지 않는다.




REFERENCES

'Database' 카테고리의 다른 글

쿼리연습 (겹치는 날짜 검사하기)  (0) 2023.04.07
SQL  (0) 2022.05.30
프로시저  (0) 2022.02.27
조인  (0) 2022.02.27
Spring Data Jpa Bulk Insert  (0) 2022.02.27