본문 바로가기

MySQL

Transaction Isolation Level

Transaction Isolation Level 설정에 따라,

트랜잭션이 데이터를 읽기 전에 읽기 락을 하냐 마냐, 읽기 락을 언제까지 유지 하냐가 결정된다.

읽기 락을 많이 걸고 오래 유지할 수록 데이터의 안정성은 좋아지지만 성능은 나빠진다.

 

Transaction Isolation Level을 설정하는 명령

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

 

Transaction Isolcation Level을 설정하는 명령을 실행하지 않았다면,

디폴트 상태는 다음과 같다.

Oracle READ COMMITTED

SQL Server READ COMMITTED

MySQL REPEATABLE READ

 

Read Uncommitted

읽기 락을 전혀하지 않는다. 그래서 빠르다.

하지만 즉 Commit 되기전의 데이터가 다른 트랜잭션에서 보인다. (Dirty Reads)

 

Dirty Reads

어떤 트랜잭션이 데이터를 수정하고 있을 때, 다른 트랜잭션에서 읽을 수 있다. 예를 들어, 게시글이 반쯤 작성되고 있는 와중에 게시글 레코드를 읽는 것이 가능하다. 

 

Dirty Reads 문제를 피하려면 Transaction Isolation Level을 Read Committed 단계로 격상해야한다.

 

Read Committed

데이터를 읽기 전에 언제나 읽기 락을 건다. 그리고 트랜잭션이 끝나면 읽기 락을 푼다.

어떤 트랜잭션이 commit된 이후에만 다른 트랜잭션에게 그 값들이 보이게하므로써 Dirty Reads 문제를 해결했다.

하지만 어떤 트랜잭션이 한 번 읽은 레코드를 다시 한번 더 읽을 때 그 사이에 다른 트랜잭션이 그 레코드를 수정하고 commit했다면, 다시 읽은 값은 처음 읽은 값과 달라진다. (non-repeatable-read 문제)

 

non-repeatable-read

예를 들어 계좌 이체하는 작업 트랜잭션이 있다고 가정하다.

계좌 이체는 먼저 잔액을 확인하는 작업을 한 후 잔액이 있으면 이체를 하는 작업으로 진행된다.

여기서 잔액을 확인하는 작업은 읽기 락이 걸리지만, 잔액 확인을 다하고나면 읽기 락이 풀린다. 이 때 다른 트랜잭션이 계좌의 쓰기 락을 걸어서 계좌의 금액 데이터를 수정할 수가 있다. 따라서 계좌 이체 실행시 에러가 발생할 수 있다.

 

non-repeatable-read 문제를 피하려면 Transaction Isolation Level을 Repeatable Read 단계로 격상해야한다.

 

Repeatable Read

데이터를 읽기 전에 읽기 락을 건다. 그리고 읽기 락은 트랜잭션이 끝날 때까지 유지해서 다른 트랜잭션이 중간에 끼어들지 못하도록 막는다 => non-repeatable-read 해결

하지만 트랜잭션이 아직 읽지 않은 코드를 다른 트랜잭션이 수정하는 것은 허용이 된다(phantom read 문제).

 

phantom read 문제를 피하려면 Transaction Isolation Level을 serializable로 격상해야 한다.

 

serializable

phantom read를 해결한다.

 

'MySQL' 카테고리의 다른 글

Transaction  (0) 2020.01.14
성능 개선  (0) 2020.01.14
RDB vs NoSQL DB  (0) 2020.01.14