Spring Data JPA 사용 시 service method에 @transactional 없이 transaction 처리되는 이유
트랜잭션 어노테이션을 작성하지 않은 메소드에서 DB호출이 있을 때 TransactionInterceptor.invoke가 호출되어 트랜잭션이 동작하는 것 처럼 보여 디버깅 해보았는데 실행되는 이유는 의외로 단순했다.
Spring Data JPA(Java Persistence API)는 Spring 에서 제공하는 모듈로 JPA를 편하게 사용할 수 있도록 도와준다.
해당 모듈에서 자주 사용하는 기능을 지원하는 JpaRepository interface 를 제공하고 있다.
우리가 JpaRepository를 상속해서서 편하게 db작업을 처리할 수 있는 이유는 기본 구현체인 SimpleJpaRepository가 JpaRepository를 상속한 JpaRepositoryImplementation를 구현하고 있기 때문이다.
SimpleJpaRepository는 @Transactional이 선언되어 있으며 어노테이션은 클래스 수준에서 모든 메서드에 기본값으로 적용됩니다.
write 메소드에는 각각 @Transactional 어노테이션이 작성되어있다.
추가로 알게된 것은 deleteById는 내부적으로 findById를 호출해 객체를 찾아
delete 메소드를 호출한다.
Repository 호출 전까지 Transaction을 제어할 수 있는 작업을 하지 않았다면, JpaRepository를 사용하는 경우 기본적으로 readOnly = true 옵션을 사용하여 동작합니다.
한 메소드에서 여러가지 db작업을 호출 시 트랜잭션 어노테이션을 선언하지 않으면 각각 트랜잭션 새로 열어 사용한다.
레거시 코드에 누락된 부분들이 있어 각각의 트랜잭션이 열렸기 때문에 TransactionInterceptor.invoke가 각각 호출된 것을 알 수 있었다.
void someMethod(){
repository.find();
repository.save();
}