트랜잭션 격리 수준
동시성 제어를 위한 트랜잭션의 격리 수준인 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE에 대해 배워봅니다.
READ UNCOMMITTED
READ UNCOMMITTED는 다른 트랜잭션의 COMMIT 여부와 상관없이 현재 데이터를 조회하는 격리 수준입니다.
한 트랜잭션에서 조회를 5번 할 경우 최대 5번 모두 다른 값이 조회될 수 있으며 이 때 DIRTY READ가 발생할 수 있습니다.
DIRTY READ: 트랜잭션 종료 시 존재하지 않을 수 있는 데이터를 조회하는 것
따라서 RDBMS에서는 표준 격리수준으로도 인정하지 않습니다.
READ COMMITTED
READ COMMITTED는 여러 RDBMS의 기본 격리 수준으로 다른 트랜잭션에서 COMMIT된 데이터를 조회하는 격리 수준입니다.
만약 다른 트랜잭션에서 값을 변경하였지만 COMMIT하지 않았다면 MVCC 매커니즘을 통해 이전 데이터 버전을 읽어옵니다.
하지만 두 번 이상 조회해야 하는 경우 중간에 다른 트랜잭션에서 값을 변경 후 COMMIT하게 된다면 NON-REPETABLE READ와 PHANTOM READ 문제가 발생할 수 있습니다.
NON-REPETABLE READ: 한 트랜잭션 내에서 같은 데이터를 조회했는데 값이 다른 경우 PHANTOM READ: 한 트랜잭션 내에서 같은 쿼리문을 실행했음에도 조회 결과가 다른 경우
따라서 READ COMMITTED는 READ UNCOMMITTED의 한계를 보완하지만, NON-REPETABLE READ와 PHANTOM READ 등이 여전히 발생합니다.
REPEATABLE READ
REPETABLE READ는 MySQL의 데이터베이스 엔진인 InnoDB의 기본 격리 수준으로 트랜잭션이 시작되기 전 COMMIT된 데이터만 조회할 수 있는 격리 수준입니다.
READ COMMITTED와 달리 다른 트랜잭션에서 값을 변경 후 COMMIT 하더라도 MVCC 매커니즘을 통해 이전 데이터 버전을 읽어옵니다.
NON-REPETABLE READ를 방지할 수 있다는 점에서 READ COMMITTED를 보완하지만 항상 이전 데이터 버전을 읽어오기 때문에 UPDATE 부정합이 발생합니다.
UPDATE 부정합: 이전 데이터 버전을 통해 UPDATE를 하더라도 실제 데이터는 변경되었기 때문에 아무 변경이 일어나지 않는 경우
따라서 REPEATABLE READ는 READ COMMITTED를 보완함과 동시에 UPDATE 부정합이 발생할 수 있으며 PHANTOM READ가 여전히 발생합니다.
SERIALIZABLE
SERIALIZABLE은 가장 단순하고 가장 엄격한 격리수준입니다. 트랜잭션이 작업 중이면 LOCKING 매커니즘을 통해 어떤 작업도 허용하지 않습니다.
이런 특징 덕분에 DIRTY READ, NON-REPETABLE READ, PHANTOM READ를 완벽하게 방지하지만, 동시처리 능력이 다른 격리수준보다 떨어지고 속도가 느립니다.
Leave a comment