트랜잭션 격리 수준
트랜잭션 격리 수준
트랜잭션 격리 수준은 서로 다른 트랜잭션이 같은 데이터에 접근할때 데이터를 처리하는 방법과 관련이 있다.
격리 수준은 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE 4가지로 나눌 수 있다.
격리 수준에 따라 발생할 수 있는 문제가 달라지는데, 이 문제는 Dirty Read, Non Repetable Read, Phantom Read 3가지가 있다.
Dirty Read | Non Repetable Read | Phantom Read | |
---|---|---|---|
READ UNCOMMITTED | O | O | O |
READ COMMITTED | X | O | O |
REPETABLE READ | X | X | O (MySQL InnoDB, PostgreSQL 는 X) |
SERIALIZABLE | X | X | X |
격리 수준
글에서 언급할 트랜잭션 A, 트랜잭션 B 는 트랜잭션을 구분하기 위해 임의로 정한 트랜잭션 이름이다.
READ UNCOMMITTED
트랜잭션 A 에서 변경한 내용을 commit 여부와 관계없이 트랜잭션 B 에서도 볼 수 있는 격리 수준이다. 이 현상을 Dirty Read 라고 한다.
Dirty Read 뿐만 아니라 Non Repeatable Read 와 Phantom Read 도 발생한다.

READ COMMITTED
트랜잭션 A 에서 commit 한 데이터만 트랜잭션 B 에서 볼 수 있으나 트랜잭션 B 에서 동일한 데이터를 조회할 때 결과가 서로 다른 Non Repeatable Read 문제가 발생할 수 있다. Non Repeatable Read 는 Update 쿼리와 연관해서 생각해볼 수 있다.
트랜잭션 A 가 시작하고 한 데이터를 update 했으나 commit 을 아직 하지 않은 상태에서 트랜잭션 B 가 동일한 데이터를 조회하면 A 가 update 하기 전의 결과가 조회된다. 그러나 A 가 commit 을 하고나서 B 의 트랜잭션이 끝나기 전에 다시 B 가 동일한 데이터를 조회하면 A 가 update 한 결과가 조회된다.
한 트랜잭션 안에서 동일한 데이터를 조회할 때 서로 다른 결과가 나올 수 있다.
Dirty Read 는 발생하지 않으나 Non Repeatable Read 뿐만 아니라 Phantom Read 도 발생한다.

REPEATABLE READ
앞에서 언급한 Dirty Read, Non Repeatable Read 문제는 발생하지 않으나 REPEATABLE READ 격리 수준에서는 Phantom Read 문제가 발생할 수 있다.
단, MySQL 의 InnoDB 와 PostgreSQL 에서는 REPEATABLE READ 격리 수준에서 Phantom Read 문제가 발생하지 않는다. MySQL InnoDB 은 디폴트 격리 수준으로 REPETABLE READ 를 사용한다.
Phantom Read 는 이름에서 느껴지듯 다른 트랜잭션의 변경에 의해 트랜잭션 내에서 데이터가 마치 유령처럼 생겼다 없어졌다 하는 현상이 발생한다. Phantom Read 는 Insert 쿼리와 연관지어 생각해볼 수 있다.
트랜잭션 A 에서 Insert 쿼리로 테이블에 (Idx: 2, Name: Steve Jobs) row 를 추가한다고 할때 insert 쿼리가 발생하기 전에 트랜잭션 B 에서 트랜잭션을 시작하고 이 테이블의 모든 row 를 조회했을 때는 (Idx: 2, Name: Steve Jobs) 가 보이지 않는다.
그러나 A 의 insert 가 발생하고 commit 까지 끝나고 나서 B 의 트랜잭션이 끝나기 전에 다시 이 테이블의 모든 row 를 조회했을 때 이전에 없었던 (Idx: 2, Name: Steve Jobs) 가 보이게 되는 현상이 Phantom Read 다.


SERIALIZABLE
가장 엄격한 격리 수준으로 Dirty Read, Non Repeatable Read, Phantom Read 문제가 발생하지 않는다. 그만큼 동시 처리 성능은 떨어지지만 데이터 정합성이 높다.
<참고>
https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
https://dev.mysql.com/doc/refman/8.0/en/glossary.html#glos_consistent_read
https://www.postgresql.kr/blog/pg_phantom_read.html
https://www.postgresql.org/docs/current/transaction-iso.html#XACT-READ-COMMITTED