hwasowl.log

트랜잭션 격리수준 본문

기술면접

트랜잭션 격리수준

화 솔 2024. 11. 26. 10:26

트랜잭션의 격리 수준은 동시에 여러 트랙션이 실행될 때 한 트랜잭션이 다른 트랜잭션의 연산에 영향을 받지 않도록 하는 정도를 의미한다. 낮게 설정한 격리 수준은 처리 능력을 높이지만, 데이터가 맞지 않는 일관성 문제를 발생시킬 수 있고 높게 설정한 격리 수준은 일관성을 보장해주지만 동시 처리 능력이 현저히 떨어질 수 있다.즉, 데이터 정합성과 성능은 반비례하므로 상황에 맞게 설정하는 것이 중요하다. 정리하자면 트랜잭션의 격리 수준은 개발자가 트랜잭션 격리 수준을 설정할 수 있는 기능을 제공하는 기능이다.

 

트랜잭션 격리 수준은 어떤 것이 있고 각각 어떤 특징이 있나?

트랜잭션의 격리 수준은 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE가 존재한다.

 


 

READ UNCOMMITTED

READ UNCOMMITTED는 커밋이 되지 않은 트랜잭션의 데이터 변경 내용을 다른 트랜잭션이 조회하는 것을 허용하는 것이다. 즉 COMMIT 이나 ROLLBACK 여부에 상관 없이 다른 트랜잭션에서 값을 읽을 수 있다는 것이다.

그러므로 격리 수준에서는 Dirty Read, Phantom Read, Non-Repeatable Read의 문제가 발생할 수 있다.

 

READ UNCOMMITTED

 


 

READ COMMITTED

READ COMMITEDCOMMIT이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회할 수 있도록 허용하는 것이다. 특정 트랜잭션이 이루어지는 동안, 다른 트랜잭션은 해당 데이터에 접근할 수 없다.

READ COMMITED - 행복한 시점

 

위 사진 상으로만 보면 커밋된 정보를 가져오기 때문에 이론상 문제가 없어 보이지만 사실 여기엔 허점이 있다.

아래의 사진을 한번 보자

 

READ COMMITED - 정합성 문제

 

트랜잭션-1이 ID 222 행을 UPDATE 했지만 커밋이 되지 않은 상태로 트랜잭션-2가 조회하면 Jeju가 아닌 Busan값을 가져온다. 하나의 트랜잭션 내에서 똑같은 SELECT 쿼리를 실행했을 때 항상 같은 결과를 가져와야 하는 REPEATABLE READ의 정합성에 어긋나게 된다.

 

그러므로 Dirty Read 문제는 발생하지 않지만, 여전히 Phantom Read, Non-Repeatable Read 문제가 발생할 수 있다.

 


 

REPEATABLE READ

일반적인 RDBMS는 변경 전의 레코드를 Undo 공간에 백업해둔다. 그러면 변경 전/후 데이터가 모두 존재하므로, 동일한 레코드에 대해 여러 버전의 데이터가 존재한다고 하여 이를 MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)라고 부른다. MVCC를 통해 트랜잭션이 롤백된 경우에 데이터를 복원할 수 있을 뿐만 아니라, 서로 다른 트랜잭션 간에 접근할 수 있는 데이터를 세밀하게 제어할 수 있다. 각각의 트랜잭션은 순차 증가하는 고유한 트랜잭션 번호가 존재하며, 백업 레코드에는 어느 트랜잭션에 의해 백업되었는지 트랜잭션 번호를 함께 저장한다. 그리고 해당 데이터가 불필요해진다고 판단하는 시점에 주기적으로 백그라운드 쓰레드를 통해 삭제한다.

- 굉장히 잘 적어주셔서 인용해왔다 [출처: https://mangkyu.tistory.com/299]

 

REPEATABLE READMVCC를 이용해 트랜잭션에서 특정 레코드를 조회할 때 항상 같은 데이터를 응답하는 것을 보장한다.

 

REPEATABLE READ

 

설명 상으로만 보면 아무 문제가 발생하지 않을 것 같지만.. 아니다. 아래 그림을 한번 보자.

REPEATABLE READ - Phantom Read

 

REPEATABLE READ는 새로운 레코드의 추가까지는 막지 않는다. 따라서 SELECT로 조회한 경우 트랜잭션이 끝나기 전에 다른 트랜잭션의 의해 추가된 레코드가 발견될 수 있는데 이를 Phantom Read라고 한다. 하지만 MVCC 덕분에 일반적인 조회에서 Phantom Read는 발생하지 않는데, 자신보다 나중에 실행된 트랙잭션이 추가한 레코드는 무시하면 되기 때문이다.

 

정리하자면 Non-Repeated Read 문제가 발생하지 않지만, Phantom Read 문제가 발생할 수 있다.

 


 

SERIALIZABLE

SERIALIZABLE은 가장 엄격한 격리 수준으로 이름 그대로 모든 트랜잭션을 순차적으로 실행시킨다.

여러 트랜잭션이 동일한 레코드에 동시 접근할 수 없는 환경이므로 어떠한 데이터 부정합 문제도 발생하지 않는다.

하지만 트랜잭션이 순차적으로 처리되어야 하므로 동시 처리 능력이 매우 떨어진다.

극단적으로 안전한 작업이 필요한 경우가 아니라면 사용해서는 안된다.

 


 

트랜잭션 격리 수준 중 발생할 수 있는 문제들 정리

Dirty Read는 한 트랜잭션이 다른 트랜잭션이 변경 중인 데이터를 읽는 경우를 의미한다.

다른 트랜잭션이 아직 커밋되지 않은 (롤백할 가능성이 있는) 데이터를 읽어서, 데이터가 나중에 롤백된 경우

데이터의 일관성을 깨뜨릴 수 있는 문제.

 

Phantom Read는 한 트랜잭션이 동일한 쿼리를 두 번 실행했을 때, 두 번의 쿼리 사이에 다른 트랜잭션이

삽입, 갱신, 삭제 등의 작업을 수행해 결과 집합이 달라지는 경우를 말한다. 이로 인해 한 트랜잭션 내에서 일관성 없는
결과를 가져오는 문제.

 

Non-Repeatable Read는 같은 트랜잭션 안에서 동일한 쿼리를 실행했을 때, 다른 결과를 얻는 경우를 의미한다.

예를 들어, 한 트랜잭션이 같은 데이터를 두 번 읽을 때, 첫 번째 읽기와 두 번째 읽기 사이에 다른 트랜잭션이 해당 데이터를

변경했을 경우 문제.