JPA의 트랜잭션
트랜잭션의 특징, ACID
Atomicity(원자성)
부분적인 성공을 허용하지 않고, All or Nothing
실패 시 모두 실패, 성공 시 모두 성공한다.
Consistency(일관성)
데이터의 정합성을 뜻한다
Isolation(독립성)
트랜잭션 내의 데이터에 대해서는 다른 트랜잭션으로부터 독립적이다.
Durability(지속성)
데이터는 영구적으로 보관된다.
CheckedException
Exception 클래스
가 CheckedException이다. 명시적으로 Exception처리를 해주어야한다.
Transaction
내에서 Exception이 발생하여도 rollback되지 않고 commit
된다.
- 개발자가 해당 예외처리에 대한 책임을 가지게 된다.
- catch 구문에서 rollback을 명시적으로 등록해주어야한다.
소스 코드 확인해보기
package org.springframework.transaction.interceptor
의 추상 클래스인 TransactionAspectSupport
를 찾아보았다.
invokeWithinTransaction()
메서드를 확인해보면 아래와 같이 구성되어 있다.
1 | try { |
Exception이 발생하면 catch 구문에 들어가게 되고
completeTransactionAfterThrowing()
메서드가 실행된다.
Transaction의 속성을 rollbackOn()
으로 체크하게 되고, true일 시 rollback()을, 아닐 결우에는 commit을 하게 된다.
1 | if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) { |
rollbackOn()메서드는 RuntimeException
과 Error
타입을 잡아낸다.
1 | public boolean rollbackOn(Throwable ex) { |
CheckedException에서 Rollback을 하는 방법
@Transactional의 소스 코드를 확인해보자. (org.springframework.transaction.annotation.Transactional)
180번 라인에 rollbackFor
라는 클래스가 있다.
1 | Class<? extends Throwable>[] rollbackFor() default {}; |
아래와 같이 명시해주면 Exception
클래스가 rollbackOn
에 들어가게 되고, rollback 메서드가 수행된다.
1 |
동일한 클래스 내에서 @Transactional 메서드 호출
1 | public class TestClass{ |
위와 같이 코드를 작성하고, test()
를 호출하면 에러가 발생해도 @Transactional이 없는 것과 같이 rollback이 되지 않고 commit
이 된다.
이는 Spring AOP
와 관련이 있다. Spring AOP는 프록시 기반으로 Bean 외부에서 메서드가 호출될 때
Annotation를 인식한다.
위 코드는 외부가 아닌 내부에서 호출을 하여 @Transactional
이 동작하지 않는 것이다.
참고 : Spring @Transaction method call by the method within the same class, does not work?
install_url
to use ShareThis. Please set it in _config.yml
.