본문 바로가기
Database

[MySQL] 트랜잭션 격리 수준

by yonikim 2025. 1. 19.
728x90

 

트랜잭션에 관해서는 아래 포스트에서 정리했다. 더 나아가서 트랜잭션의 격리 수준에 대해서 정리해보자.

- https://yonikim.tistory.com/154 

 

 

트랜잭션의 격리 수준이란 여러 트랜잭션이 동시에 실행될 때, 특정 트랜잭션이 다른 트랜잭션에서 변경하거나 조회하는 데이터를 볼 수 있게 허용할지 여부를 결정하는 것이다. 

낮은 격리 수준은 동시 처리 능력을 높이지만, 데이터의 일관성 문제를 발생시킬 수 있다. 반대로 높은 격리 수준은 데이터의 일관성을 보장하지만, 동시 처리 능력이 떨어질 수 있다.

즉, 데이터 정합성과 성능은 반비례한다.  

 

트랜잭션 격리 수준의 종류와 특징 

1. READ UNCOMMITTED 

커밋이 되지 않은 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용한다. 해당 격리 수준에서는 Dirty Read, Phantom Read, Non-Repeatable Read 문제가 발생할 수 있다. 

 

2. READ COMMITTED

커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회할 수 있도록 허용한다. 특정 트랜잭션이 이루어지는 동안, 다른 트랜잭션은 해당 데이터에 접근할 수 없다. Dirty Read는 발생하지 않지만, Phantom Read, Non-Repeatable Read 문제가 발생할 수 있다.

 

3. REPEATABLE READ

일반적으로 RDBMS는 변경 전의 레코드를 언두 공간에 백업해둔다. 그러면 변경 전/후 데이터가 모두 존재하므로, 동일한 레코드에 대해 여러 버전의 데이터가 존재한다고 하여 이를 MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어) 라고 부른다.

REPEATABLE READ는 MVCC를 이용해 한 트랜잭션 내에서 동일한 결과를 보장하지만, 새로운 레코드가 추가되는 경우엔 부정합이 생길 수 있다.

  • SELECT FOR UPDATE 이후 SELECT: 갭락 때문에 Phantom Read X
  • SELECT FOR UPDATE 이후 SELECT FOR UPDATE: 갭락 때문에 Phantom Read X
  • SELECT 이후 SELECT: MVCC 때문에 Phantom Read X
  • SELECT 이후 SELECT FOR UPDATE: Phantom Read O

4. SERIALIZABLE  

가장 엄격한 격리 수준으로, 이름 그대로 트랜잭션을 순차적으로 진행시킨다. 

SERIALIZABLE는 특정 트랜잭션이 사용중인 테이블의 모든 행을 다른 트랜잭션이 접근할 수 없도록 잠그므로, 가장 높은 데이터 정합성을 가진다. 하지만 트랜잭션이 순차적으로 처리되어야 하므로 동시 처리 성능이 매우 떨어진다.

MySQL의 경우 단순한 SELECT 쿼리가 실행되더라도 데이터베이스 잠금이 걸려서 다른 트랜잭션에서 데이터에 접근할 수 없다. 

 

 

Dirty...? Phantom...? 이게 대체 무슨 문제야?

Dirty Read는 한 트랜잭션이 다른 트랜잭션이 변경 중인 데이터를 읽는 경우 발생한다. 다른 트랜잭션이 아직 커밋하지 않은(즉, 롤백할 가능성이 있는) 데이터를 읽어서, 그 데이터가 나중에 롤백될 경우 트랜잭션의 결과가 변경될 수 있다. 이는 데이터의 일관성을 깨뜨릴 수 있다.

 

Phantom Read는 한 트랜잭션이 동일한 쿼리를 두 번 실행했을 때, 두 번의 쿼리 사이에 다른 트랜잭션이 삽입, 갱신, 삭제 등의 작업을 수행하여 결과 집합이 달라지는 경우를 말한다. 이로 인해 한 트랜잭션 내에서 일관성 없는 결과를 가져올 수 있다.

 

Non-Repeatable Read는 같은 트랜잭션 안에서 동일한 쿼리를 실행했을 때, 다른 결고를 얻는 경우를 의미한다. 예를 들어, 한 트랜잭션이 같은 데이터를 두 번 읽을 때, 첫 번째 읽기와 두 번째 읽기 사이에 다른 트랜잭션이 해당 데이터를 변경했을 경우 발생할 수 있다.

 

 

[References]

https://mangkyu.tistory.com/299

 

 

 

728x90

'Database' 카테고리의 다른 글

[Database] SQL Injection  (0) 2025.01.09
[MySQL] 트랜잭션 (Transaction)  (1) 2024.01.05
[Mongo] 백업 및 복원하기  (0) 2021.08.27