본문 바로가기
스터디/MySQL

READ COMMITED와 REPEATABLE READ 비교

by Big Sun 2025. 1. 6.
728x90


트랜잭션의 격리 수준(isolation level)은 여러 트랜잭션이 동시에 실행될 때, 특정 트랜잭션이 다른 트랜잭션의 변경사항이나 데이터를 조회할 수 있는지를 결정하는 중요한 설정입니다. MySQL은 총 4가지 격리 수준을 제공합니다.

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

이 중에서 READ UNCOMMITTED는 커밋되지 않은 데이터를 읽는 Dirty Read 문제를 일으킬 수 있고, SERIALIZABLE은 동시 처리 성능이 낮아지는 단점 때문에 거의 사용되지 않습니다.

따라서 이번 포스팅에서는 가장 자주 사용되는 READ COMMITTEDREPEATABLE READ를 중심으로, 두 격리 수준의 차이점과 특징을 살펴보겠습니다.

READ COMMITTED

READ COMMITTED 격리 수준에서는 커밋된 데이터만 읽을 수 있습니다. 이 덕분에 Dirty Read 문제가 발생하지 않으며, 데이터의 일관성을 어느 정도 보장할 수 있습니다.



READ COMMITTED 격리 수준부터는 Undo Log를 활용하여 데이터 변경 전의 상태를 저장합니다. 이를 통해, "커밋된 데이터만 읽는다"는 READ COMMITTED의 규칙을 준수하면서도 다른 트랜잭션에서 변경 중인 데이터에 접근할 수 있습니다.

Undo Log는 데이터가 변경되기 전의 상태를 저장해두어, 트랜잭션이 커밋되기 전에도 안정적인 조회를 가능하게 합니다. 이를 통해 데이터의 가용성을 높이면서도 격리 수준을 유지할 수 있습니다.

그러나, "커밋된 데이터만 읽는다"는 READ COMMITTED의 규칙은 “하나의 트랜잭션에 같은 조회 쿼리를 여러번 수행하더라도 결과가 같아야 한다”는 REPEATABLE READ를 만족하지 못합니다.


위 그림처럼 update를 한 이후에 바로 commit되었다고 할 때 다른 트랜잭션이 한 번의 트랜잭션에서 같은 select 쿼리를 2번 실행하였을 때 결과가 달라지게 됩니다.


READ COMMITTED

 

REPEATABLE READ는 데이터 일관성을 다음과 같은 방식으로 보장합니다.

  1. 트랜잭션 순서 부여

    모든 트랜잭션에는 고유한 순서 번호가 부여되며, 이 순서는 트랜잭션이 생성될 때마다 계속 증가합니다.

  2. 순서 기반 데이터 접근 제한

    특정 트랜잭션은 자신의 순서 번호 이하인 트랜잭션에서 변경한 것만 접근할 수 있다.



이렇게 되면,10번 트랜잭션은 트랜잭션 번호가 같거나 낮은 트랜잭션에서 변경된 레코드에만 접근할 수 있기 때문에 트랜잭션 12에서 id = 500000인 레코드를 수정한 결과가 반영된 레코드에는 접근할 수 없다.

즉, NON-REPEATABLE READ 문제를 방지합니다.

READ COMMITTED와 REPEATABLE READ 둘 다 MVCC를 이용해 commit 되기 전 데이터를 보여주는 것은 동일하지만, REPEATABLE READ에서는 언두 영역에 백업된 레코드의 여러 버전 중 몇 번째 이전 버전까지 조회할 수 있냐가 다릅니다.

728x90