트랜잭션 격리수준 (Isolation Level)에 대해 학습하고 나서 다음과 같은 의문이 들었습니다.
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Reflective
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
String[] label() default {};
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default -1;
String timeoutString() default "";
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
@Transcational의 라이브러리 클래스를 직접 확인했습니다
여기서 트랜잭션 격리수준은 isolation 속성을 통해 지정할 수 있습니다
public enum Isolation {
DEFAULT(-1),
READ_UNCOMMITTED(1),
READ_COMMITTED(2),
REPEATABLE_READ(4),
SERIALIZABLE(8);
private final int value;
private Isolation(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
다시 Isolation enum을 확인해보면 위와같은 속성을 확인할 수 있습니다
기본적으로 DEFAULT속성이 적용되며,
READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE 속성을
적용할 수 있습니다
나머지 트랜잭션 격리수준은 앞서 학습한대로 동작하며, 그에 따른 문제도 동일하게 발생합니다
그렇다면 DEFAULT 속성은 어떻게 동작할까요?
정말 단순하게도 연결된 DB의 트랜잭션 격리수준을 따릅니다.
만약 MYSQL을 연결했다면 REPEATABLE_READ로 동작하고, Oracle을 연결했다면
READ_COMMITTED로 동작합니다
@Transcational을 적용하고 아무런 설정을 하지 않으면 DB의 트랜잭션 격리수준을 따릅니다
우리가 해당 개발한 애플리케이션에서 동시성 문제가 크게 발생하지 않은 이유는
이렇게 DB의 안전한 트랜잭션 격리수준을 따랐기 때문입니다!