MySQL의 트랜잭션 격리 수준과 스프링의 @Transactional 기본 격리 수준(Isolation Level)

주리링·2022년 6월 18일
3

우테코 생존기

목록 보기
9/17
post-thumbnail

격리 수준

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

그렇다면 격리 수준에는 어떤 것이 있을까?

READ UNCOMMITTED

어떤 트랜잭션의 변경 내용이 COMMIT되든 ROLLBACK 되든 상관없이 다른 트랜잭션에서 조회 할 수 있다.

  • 더티 리드가 허용되는 격리 수준
    - 더티 리드 : 어떤 트랜잭션에서 처리한 작업이 완료되지 않았는데도 다른 트랜잭션에서 볼 수 있는 현상

READ COMMITTED

COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
데이터가 변경되는 동안은 조회할 수 없다.

그림과 같이 id가 1인 row의 name를 수정하려고 하면 undo 영역에 수정 전 정보가 저장된다.
이 때, 격리 수준이 READ COMMITTED라면 undo 영역의 id가 1인 값을 읽어온다.
하지만 COMMIT후엔 수정된 값을 읽어온다.

REPEATABLE READ

자신의 트랜잭션이 생성되기 이전의 트랜잭션의 COMMIT된 데이터만 조회한다.

  • InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준

REPEATABLE READ에서는 트랜잭션의 생성 순으로 index가 생긴다.
그래서 자신의 트랜잭션 이후의 트랜잭션에서 commit한 데이터는 조회할 수 없다.

SERIALIZABLE

트랜잭션이 사용하는 데이터에 대한 격리와 순서만 보장된다면 데이터를 조회할 수 있다.

예를 들어, Transaction1과 Transaction2가 A라는 값을 읽고 쓰고 B라는 값을 읽고 쓴다고 가정하자.
위의 가정을 듣고 과정을 순서대로 적으면 다들 아래와 같이 생각할 것이다.
T1{R(A) W(A) R(B) W(B)} T2{R(A) W(A) R(B) W(B)}

하지만 격리 수준이 SERIALIZABLE일 때, 아래의 순서처럼도 데이터 조회를 할 수 있다.
T1{R(A) W(A)} T2{R(A) W(A)} T1{R(B) W(B)} T2{R(B) W(B)}

즉, 읽는 순서가 변경된 데이터에 대해서 보장이 된다면 데이터를 조회할 수 있다.

그렇다면 스프링에서 @Transactional의 기본 격리 수준은 어떻게 될까?

Transactional 클래스에 따르면 아래와 같이 나와있다.

기본 격리 수준은 DEFAULT로 설정되어 있다.
이 DEFAULT란 무엇일까?

datastore(database)에 기본 격리 수준을 따른다는 것을 의미한다.
즉, MySQL 5.5부터 대부분 스토리지 엔진으로 InnoDB를 사용하고 있으므로 DataBase를 MySQL로 사용한다면, @Transactional의 기본 격리 수준은 REPEATABLE READ이다.

profile
코딩하는 감자

0개의 댓글