Spring&Spring Boot
(Spring/Spring Boot) transactional annotation 속성 격리 isolation
Developer RyanKim
2020. 2. 19. 21:57
@Transactional isolation 옵션 종류 및 설명
* Isolation (= 격리) : 트랜잭션의 격리 수준을 설정하는 속성
사실 @Transacitonal의 속성일 뿐만 아니라 기본적으로 트랜잭션은 4단계의 격리 수준이 존재합니다.
이 격리수준을 설정하는 속성이 isolation 속성 입니다.
Isolation Level
Level 1. READ UNCOMMITED (커밋되지 않은 읽기)
: Dirty Read / Non-repeatable read / phantom read 발생가능
Level 2. READ COMMITED (커밋된 읽기)
: Non-repeatable read / phantom read 발생가능
Level 3. REPEATABLE READ (반복 가능한 읽기)
: phantom read 발생가능
Level 4. SERIALIZABLE (직렬화 가능)
: 격리수준에 따른 문제 발생 X
여기서, 격리수준에 따른 문제가 무엇인지 살펴보면
Dirty Read
: 트랜잭션 1이 수정중인 데이터를 트랜잭션 2가 읽을 수 있다. 만약 트랜잭션 1의 작업이 정상 커밋되지 않아 롤백되면, 트랜잭션 2가 읽었던 데이터는 잘못된 데이터가 될 것이다. (데이터 정합성에 어긋남)
Non-repeatable read
: 트랜잭션 1이 회원 A를 조회중에 트랜잭션 2가 회원 A의 정보를 수정하고 커밋한다면, 트랜잭션 1이 다시 회원A 를 조회했을 때는 수정된 데이터가 조회된다 (이전 정보를 다시 조회할 수 없음). 이처럼 반복해서 같은 데이터를 읽을 수 없는 경우이다.
Phantom read
: 트랜잭션 1이 10살 이하의 회원을 조회했는데 트랜잭션 2가 5살 회원을 추가하고 커밋하면 트랜잭션 1이 다시 10살 이하 회원을 조회했을 때 회원 한명이 추가된 상태로 조회된다. 이처럼 반복 조회시 결과집합이 달라지는 경우이다.
package org.springframework.transaction.annotation
enum Isolation
더보기
public enum Isolation {
/**
* Use the default isolation level of the underlying datastore.
* All other levels correspond to the JDBC isolation levels.
* @see java.sql.Connection
*/
DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
/**
* A constant indicating that dirty reads, non-repeatable reads and phantom reads
* can occur. This level allows a row changed by one transaction to be read by
* another transaction before any changes in that row have been committed
* (a "dirty read"). If any of the changes are rolled back, the second
* transaction will have retrieved an invalid row.
* @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED
*/
READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
/**
* A constant indicating that dirty reads are prevented; non-repeatable reads
* and phantom reads can occur. This level only prohibits a transaction
* from reading a row with uncommitted changes in it.
* @see java.sql.Connection#TRANSACTION_READ_COMMITTED
*/
READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
/**
* A constant indicating that dirty reads and non-repeatable reads are
* prevented; phantom reads can occur. This level prohibits a transaction
* from reading a row with uncommitted changes in it, and it also prohibits
* the situation where one transaction reads a row, a second transaction
* alters the row, and the first transaction rereads the row, getting
* different values the second time (a "non-repeatable read").
* @see java.sql.Connection#TRANSACTION_REPEATABLE_READ
*/
REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
/**
* A constant indicating that dirty reads, non-repeatable reads and phantom
* reads are prevented. This level includes the prohibitions in
* {@code ISOLATION_REPEATABLE_READ} and further prohibits the situation
* where one transaction reads all rows that satisfy a {@code WHERE}
* condition, a second transaction inserts a row that satisfies that
* {@code WHERE} condition, and the first transaction rereads for the
* same condition, retrieving the additional "phantom" row in the second read.
* @see java.sql.Connection#TRANSACTION_SERIALIZABLE
*/
SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
private final int value;
Isolation(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}