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;
	}

}