격리 수듄 하고는 ㅋㅋㅋ
글의 첫째줄에서 이상한 말이 보이는 것 같다고? 마음이 나쁜 독자에겐 그런 말이 보인다는 소문이 있다던데, 스스로를 다시 한번 성찰해보기 바란다.
농담이다.
이번 글에서는 데이터베이스 트랜잭션 격리 수준(transaction isolation level)에 대해 알아본다.
트랜잭션 격리 수준이란, DBMS에서 트랜잭션을 어느정도로 보장할 지 결정하는 level이다. 그리고, 이 level에 따라 발생하는 트랜잭션의 문제점이 각각 달라진다. 정확히는, 그 개수가 달라진다.
커밋되지 않은 값을 읽는다. 딱 봐도 엄청 위험해보이지 않는가?
당신의 직감이 들어맞았다. 이 격리 수준에서는 커밋되지 않은 트랜잭션 수행값도 모조리 읽어온다. 일반적으로는, 그때마다 최신 업데이트 된 값을 읽어오게 된다. 실제 DB에 사용하면 매우 위험한 격리 수준이다. 이 수준에서 발생하는 문제점들은 다음과 같다.
problems | Dirty read | Non-repeatable read | Phantom read |
---|---|---|---|
O/X | O | O | O |
이번에는 커밋된 값을 읽어온다. 당연하게도, Dirty read 문제점이 해결된다. 다만, 자원에 대한 update나 create는 lock이 걸리지 않으므로, non-repeatable read와 phantom read 문제점은 동일하게 일어난다.
problems | Dirty read | Non-repeatable read | Phantom read |
---|---|---|---|
O/X | X | O | O |
이는 MYSQL의 기본 동작 모드이다. 그림을 통해 자세히 알아보자.
repeatable read는 하나의 트랜잭션이 실행될때 그 트랜잭션에 번호를 부여하고, 그 트랜잭션 번호가 자신의 번호보다 작은 트랜잭션에 의해 변경된 데이터만 읽어온다. 그림에서 12번 트랜잭션이 커밋을 완료해도, 12번은 10번 트랜잭션의 번호보다 크므로 그 데이터를 읽어오지 않고 update시 undo 영역에 저장된 데이터를 불러온다. 이렇게 하여 non-repeatable 문제를 해결할 수 있다.
다만, insert나 delete가 일어날 경우, select에 의해 선택되는 행의 개수 자체가 달라져 phantom read problem이 발생할 수있다.
다만, 특이하게도 MYSQL에서는 순수한 select에 한하여 phantom read problem이 일어나지 않는데, 이는 트랜잭션이 발생한 순간에 스냅샷을 저장하고, 그 스냅샷에서 데이터를 가지고 오기 때문이라고 한다.
그런데 select for update 구문의 경우, phantom read problem이 발생하게 된다.
problems | Dirty read | Non-repeatable read | Phantom read |
---|---|---|---|
O/X | X | X | O |
트랜잭션을 무조건 한번에 하나씩만 실행한다. 당연히 문제점들은 발생하지 않지만, 성능이 무척 느리다!
problems | Dirty read | Non-repeatable read | Phantom read |
---|---|---|---|
O/X | X | X | X |
이렇게 트랜잭션 고립 수준에 대해 알아보았다. 특히, repeatable read level
을 적용했을 때, mysql DB
가 가진 특성이 인상적이었다.
아! 어렵다! DB!
https://jupiny.com/2018/11/30/mysql-transaction-isolation-levels/
https://joont92.github.io/db/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80-isolation-level/
https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation
https://sabarada.tistory.com/117