@Transactional
@Transactional 에 대해서 알아보자
Last updated
@Transactional 에 대해서 알아보자
Last updated
스프링에서 트랜잭션 처리는 보통 @Transactional 어노테이션을 많이 사용하게 된다. @Transactional은 클래스 또는 메소드에 사용할 수 있으며 @Transactional이 포함된 메소드가 호출될 경우, 프록시 객체가 생성된다.
프록시 객체는 해당 메소드 실행 이전에 PlatformTransactionManager를 사용하여 트랜잭션을 시작하고 결과에 따라 Commit 또는 Rollback 한다.
CheckedException or 예외가 없을 때는 Commit
UncheckedException이 발생하면 Rollback
@Transactional은 우선 순위를 가진다.
클래스 메소드
클래스
인터페이스 메소드
인터페이스
@Transactional 어노테이션 같은 경우 Spring AOP를 이용하게 되는데 이 AOP는 기본적으로 Dynamic Proxy를 이용한다.Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을경우 트랜잭션이 동작하지 않는다.
인터페이스 없이 트랜잭션 동작하게 하려면 CGLib(Code Generation Library) Proxy를 이용하면 된다.CGLib Proxy는 클래스에 대한 Proxy가 가능하기 때문에 인터페이스가 없어도 된다.
@Transactional 설정
속성
타입
설명
value
String
사용할 트랜잭션 관리자
propagation
enum: Propagation
선택적 전파 설정
isolation
enum: Isolation
선택적 격리 수준
readOnly
boolean
읽기/쓰기 vs 읽기 전용 트랜잭션
timeout
int (초)
트랜잭션 타임 아웃
rollbackFor
Throwable 로부터 얻을 수 있는 Class 객체 배열
롤백이 수행되어야 하는, 선택적인 예외 클래스의 배열
rollbackForClassName
Throwable 로부터 얻을 수 있는 클래스 이름 배열
롤백이 수행되어야 하는, 선택적인 예외 클래스 이름의 배열
noRollbackFor
Throwable 로부터 얻을 수 있는 Class 객체 배열
롤백이 수행되지 않아야 하는, 선택적인 예외 클래스의 배열
noRollbackForClassName
Throwable 로부터 얻을 수 있는 클래스 이름 배열
롤백이 수행되지 않아야 하는, 선택적인 예외 클래스 이름의 배열
@Transactional은 프록시 기반으로 동작하기 때문에 public method가 아니면 동작하지 않는다.
만약 private 에 @Transactional을 적용한다고 하면 IDE에서 컴파일 오류를 확인할 수 있다.
외와 같은 원인으로 프록시 기반으로 동작하기 때문에 외부에서 접근할 때 AOP를 통해서 프록시 객체를 접근할 수 있다. 그러나 클래스내에서 다른 메소드를 호출하게 되면 프록시로 접근하지 않고 직접 접근하기 때문에 메소드에 선언해 놓은 @Transactional 이 정상적으로 동작하지 않을 것이다.
가장 간단한 방법은 새로운 클래스를 생성하여 메소드를 위임하는 것이다.
클래스 생성이 어렵다면 aspectj를 사용하면 된다.