Skip to content

Instantly share code, notes, and snippets.

@leewin12
Created December 21, 2018 07:30
Show Gist options
  • Save leewin12/8be65f5c28b2ce3c221d124ad5150c35 to your computer and use it in GitHub Desktop.
Save leewin12/8be65f5c28b2ce3c221d124ad5150c35 to your computer and use it in GitHub Desktop.
Spring transaction의 rollback 처리에 대한 주의사항 정리

요약 @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.TransactionAspectSupportinvokeWithinTransaction method의 completeTransactionAfterThrowing(txInfo, ex);commitTransactionAfterReturning(txInfo);의 호출 여부를 구분해본다.

@leewin12
Copy link
Author

hibernatehideexception
JpaRepository.getOne에 대해 Hibernate가 javax.persistence.EntityNotFoundException을 Proxy로 감싸서 Spring Tx가 exception으로 인식하지 못하는 상황

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment