요약 @Transactional 처리가 필요한 메소드는, 해당 메소드 내에서 사용되는 모든 메소드에 명시적으로 @Transactional을 처리해주는게 안전하다.
이하 내용
-
Spring JDK Dynamic Proxy는 proxy 처리가 필요가 없거나 (@transactional등), 따로 옵션을 켜주지 않는 한, proxy obj를 만들지 않는다.
-
따라서 proxy가 없는 class에 대해서는 당연히 tx 영역으로 잡히지 않고, proxy가 없는 외부 class의 method 호출 결과에 대해 try/catch 처리를 할 경우, spring tx manger는 rollback을 하지 않습니다.
-
proxy가 있는 경우에도, 외부 class의 method를 @transactional 없이 호출 할 경우, transactionl이 none으로 인식되어, 호출 결과에 대해 try/catch 처리를 할 경우, spring tx manger는 rollback을 하지 않습니다.
-
Hibernate를 사용할 경우, JpaRepository.getOne에서 해당되는 결과가 없을 경우 발생되는 Exception은 Throwable이 맞지만, 실제로는 Hibernate Object Proxy로 감춰져 있기 때문에, Throwable로 인식되지 않아서, spring tx manager는 rollback을 하지 않습니다.
-
명확하게 확인을 하고 싶을 경우,
org.springframework.transaction
의 log level을 debug로 올려서 확인하거나,org.springframework.transaction.interceptor.TransactionAspectSupport
의invokeWithinTransaction
method의completeTransactionAfterThrowing(txInfo, ex);
와commitTransactionAfterReturning(txInfo);
의 호출 여부를 구분해본다.
JpaRepository.getOne
에 대해 Hibernate가javax.persistence.EntityNotFoundException
을 Proxy로 감싸서 Spring Tx가 exception으로 인식하지 못하는 상황