본문 바로가기
Database

[MySQL] 트랜잭션의 격리 수준(isolation level)

by EricJeong 2020. 3. 1.

격리 수준이란?

트랜잭션의 격리 수준이란 여러 트랜잭션이 동시에 처리될 때 서로 다른 트랜잭션에서 변경, 조회하는 데이터를 어느 수준에서 볼 수 있는지 설정하는 것 입니다. 격리 수준이 낮은 순서부터 'READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE' 총 4가지의 격리 수준이 있습니다.

 

MySQL은 데이터의 변경시 변경 전 데이터를 UNDO 영역에 저장하고, 변경된 데이터는 바로바로 레코드에 저장합니다. 그렇기 때문에 격리된 데이터를 조회할 때에는 테이블에서 바로 조회하는 것이 아닌, UNDO영역에 백업된 레코드를 가져와 조회합니다.

 

격리 수준에 따라 발생할 수 있는 문제점

DIRTY READ

트랜잭션에서 작업이 다 끝나지 않았지만 다른 트랜잭션에서 작업 내용을 볼 수 있는 것을 DIRTY READ라고 합니다. 변경된 데이터가 롤백될지, 커밋될지 모르는 상황에서 작업 내용을 조회할 수 있기 때문에 데이터 정합성에 큰 문제를 유발할 수 있습니다.

 

NON REPEATABLE READ

하나의 트랜잭션에서는 같은 SELECT문으로 조회할 때 항상 같은 결과를 가져와야 합니다. 이를 REPEATABLE READ라고 부르는데 SELECT할 때 마다 다른결과를 받을 수 있다면 이를 NON REPEATABLE READ상태라고 부릅니다.

 

PHANTOM READ

하나의 트랜잭션에서 같은 SELECT문으로 조회할 때 이전 SELECT에서는 존재하지 않던 값이 다음 SELECT에 조회되는 것을 의미합니다.

 

 

격리 수준

READ UNCOMMITTED

트랜잭션에서 변경하는 내용이 commit과 rollback여부에 관계 없이 다른 트랜잭션에게 노출됩니다. 

발생 가능한 문제점 - DIRTY READ, NON REPEATABLE READ, PHANTOM READ

 

READ COMMITTED

트랜잭션에서 변경한 레코드는 commit이 완료된 데이터만 조회할 수 있게 만듭니다. commit 전에 조회를 시도한다면 UNDO영역에 백업된 레코드를 조회할 수 있습니다.

발생 가능한 문제점 - NON REPEATABLE READ, PHANTOM READ

 

REPEATABLE READ

REPEATABLE READ는 InnoDB 엔진에서 사용하는 기본 격리 수준입니다. 따로 격리 수준을 설정해주지 않았다면 REPEATABLE READ 격리 수준으로 트랜잭션이 실행됩니다. REPEATABLE READ란 하나의 트랜잭션 내부에서 같은 SELECT문은 항상 같은 결과를 보여주는 것입니다. MySQL InnoDB에서는 트랜잭션별로 식별자를 주고 트랜잭션에서 변경하는 데이터를 UNDO영역에 백업합니다. 이 백업된 데이터와 트랜잭션 식별자로 동일 트랜잭션에서 동일 결과값을 보여줄 수 있도록 보장합니다.

발생 가능한 문제점 - PHANTOM READ (InnoDB는 발생하지 않음)

 

SERIALIZABLE

격리수준중 가장 높은 격리 수준입니다. 레코드를 조회할 때 Shared Lock을 획득해야만 조회할 수 있고, 데이터를 변경할 때에는 Exclusive Lock을 획득해야만 변경할 수 있습니다. 즉 한 트랜잭션에서 사용하는 데이터는 다른 트랜잭션에서 접근할 수 없게 만듭니다. 데이터 정합성을 지키는 면은 가장 우수하지만 동시 처리 성능이 떨어집니다.

 

 

 

Reference

Real MySQL

 

댓글