토비 스프링 공부하다가 트랜잭션 내부 로직 디버깅해봤는데 복잡해서 내가 제대로 이해했는지 모르겠음

이해한대로 흐름 써볼테니 틀린 부분 있으면 확인좀

스프링 부트 + JPA 사용

서비스에 @Transactional 명시

서비스 로직에서 JpaRepository.save() 호출 시

  • 컨트롤러에서 서비스 로직 호출
  • 트랜잭션 프록시 호출
  • 트랜잭션 초기 참여이므로 물리 트랜잭션 & 논리 트랜잭션 생성
  • 트랜잭션 세팅(트랜잭션 리소스 동기화 등) 이후 서비스 원본 로직 호출
  • 서비스 로직 수행하다가 원본 리포지토리 로직(JpaRepository.save()) 호출
  • JpaRepository.save()에는 @Transaction이 붙어 있으므로 트랜잭션 전파 속성이 REQUIRED로 동작
  • 물리 트랜잭션은 이미 서비스 트랜잭션이 있으므로 논리 트랜잭션으로 참여
  • 리포지토리 로직 수행

여기서 리포지토리 로직, 서비스 로직 모두 정상 수행했다고 가정하면

  • JpaRepository 논리 트랜잭션 완료 처리(이전 트랜잭션인 서비스 논리 트랜잭션으로 세팅, 콜백 실행 등등)
  • 서비스 논리 트랜잭션 완료 처리
  • 서비스 물리 트랜잭션에서 논리 트랜잭션으로부터 세팅된 롤백 마크가 없으므로 커밋 실행

리포지토리 로직에서 예외가 발생하고 이걸 리포지토리에서 서비스로 던졌다고 가정하면

  • JpaRepository 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
  • JpaRepository 논리 트랜잭션 완료 처리
  • 서비스 논리 트랜잭션에서 예외가 발생했으므로(리포지토리에서 던진 예외) 롤백 마크 세팅
  • 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행

리포지토리 로직에서 예외가 발생했는데 리포지토리에서 이 예외를 처리했다고 가정하면

  • JpaRepository 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
  • JpaRepository 논리 트랜잭션 완료 처리
  • 서비스 논리 트랜잭션 완료 처리
  • 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행

리포지토리 로직은 정상 수행했는데 서비스에서 예외가 발생했다고 가정하면

  • JpaRepository 논리 트랜잭션 완료 처리
  • 서비스 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
  • 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행

이 흐름이 맞는지랑

@Transactional이 논리 트랜잭션 선언하는거라 물리 트랜잭션이 없으면 물리 & 논리 둘 다 만드는걸로 이해했는데

그럼 논리 트랜잭션에서 롤백 마크 세팅을 안했는데 물리 트랜잭션에서 바로 예외를 감지해서 롤백하는 경우는 없는지?가 궁금함