토비 스프링 공부하다가 트랜잭션 내부 로직 디버깅해봤는데 복잡해서 내가 제대로 이해했는지 모르겠음
이해한대로 흐름 써볼테니 틀린 부분 있으면 확인좀
스프링 부트 + JPA 사용
서비스에 @Transactional 명시
서비스 로직에서 JpaRepository.save() 호출 시
- 컨트롤러에서 서비스 로직 호출
- 트랜잭션 프록시 호출
- 트랜잭션 초기 참여이므로 물리 트랜잭션 & 논리 트랜잭션 생성
- 트랜잭션 세팅(트랜잭션 리소스 동기화 등) 이후 서비스 원본 로직 호출
- 서비스 로직 수행하다가 원본 리포지토리 로직(JpaRepository.save()) 호출
- JpaRepository.save()에는 @Transaction이 붙어 있으므로 트랜잭션 전파 속성이 REQUIRED로 동작
- 물리 트랜잭션은 이미 서비스 트랜잭션이 있으므로 논리 트랜잭션으로 참여
- 리포지토리 로직 수행
여기서 리포지토리 로직, 서비스 로직 모두 정상 수행했다고 가정하면
- JpaRepository 논리 트랜잭션 완료 처리(이전 트랜잭션인 서비스 논리 트랜잭션으로 세팅, 콜백 실행 등등)
- 서비스 논리 트랜잭션 완료 처리
- 서비스 물리 트랜잭션에서 논리 트랜잭션으로부터 세팅된 롤백 마크가 없으므로 커밋 실행
리포지토리 로직에서 예외가 발생하고 이걸 리포지토리에서 서비스로 던졌다고 가정하면
- JpaRepository 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
- JpaRepository 논리 트랜잭션 완료 처리
- 서비스 논리 트랜잭션에서 예외가 발생했으므로(리포지토리에서 던진 예외) 롤백 마크 세팅
- 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행
리포지토리 로직에서 예외가 발생했는데 리포지토리에서 이 예외를 처리했다고 가정하면
- JpaRepository 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
- JpaRepository 논리 트랜잭션 완료 처리
- 서비스 논리 트랜잭션 완료 처리
- 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행
리포지토리 로직은 정상 수행했는데 서비스에서 예외가 발생했다고 가정하면
- JpaRepository 논리 트랜잭션 완료 처리
- 서비스 논리 트랜잭션에서 예외가 발생했으므로 롤백 마크 세팅
- 서비스 물리 트랜잭션에서 커밋 시도 → 롤백 마크를 보고 롤백 실행
이 흐름이 맞는지랑
@Transactional이 논리 트랜잭션 선언하는거라 물리 트랜잭션이 없으면 물리 & 논리 둘 다 만드는걸로 이해했는데
그럼 논리 트랜잭션에서 롤백 마크 세팅을 안했는데 물리 트랜잭션에서 바로 예외를 감지해서 롤백하는 경우는 없는지?가 궁금함
레포 안에서 캐치한 예외는 밖으로 전파 안됨
리포지토리 로직에서 예외가 발생했는데 리포지토리에서 이 예외를 처리했다고 가정하면 << 이 부분이면 예외가 밖으로 전파는 안되는데 롤백 마크 자체는 세팅하지 않음?
생각해보니 원본 로직에서 try-catch로 처리하면 트랜잭션 프록시까지 전파가 안되니 롤백 마크 세팅도 안될거같네 디버깅 다시해봐야겠다
프록시라는관점에서 캐치로잡았으면 예외가터졌는지를 알수가없음
우형블로그에 검색하면 니랑비슷한고민나온다 2019년인가쯤 글임
ㄳㄳ 찾아봄
논리트랜잭션에서 롤백마크세팅을안했는데 물리에서 예외감지는 뭔소린지모르겠네
어디부분? 내가 실수한거같은데
맨마지막문장
그냥 논리 트랜잭션에서 롤백 마크 세팅 안했는데 물리 트랜잭션에서 뜬금없이 예외같은 거 때문에 롤백하는 경우가 있는지 궁금했음 이런 경우는 그냥 아예 없나
할수있지 커밋하려고시도했더니 acid 벗어나서 제약조건터진다거나
그러네 acid 나오니까 바로 이해됨 ㄳㄳ
읽기 싫어
지금보니 예시도 좀 이상하네 디버깅이랑 조사좀 더해보고 다시 질문하겠음
애초에 트랜잭션 aop의 캐치에 논리 트랜잭션 롤백 체크하는게 있지 않을까? 레포에서 캐치로 잡아서 정상흐름으로 바꿔버리면 예외처리를 이미한거라 롤백안할듯 - dc App
글 느낌이 jdbc쓸때 어떻게 트랜잭션을 시작하고 언제 커밋하고 언제 롤백하는지 모르는 거 같음 - dc App
그러게 내가 뭔가 이상하게 생각한듯
영한씨 spring data블로그 글 찾아봐. jdbc로 트랜잭션 열고 커밋 롤백하는거 코드 그대로 나와있음 - dc App
TransactionAspectSupport에서 원본 로직 호출하고 거기 catch에서 completeTranasctionAfterThrowing() 호출하고 메서드 내부에서 TransactionInfo에 있던 TransactionManager 꺼내서 롤백 수행하는거 디버깅으로 확인했는데 이상하게 착각했네
우형 글이랑 알려준 글도 확인해보겠음 ㄳㄳ
잘 알고있네 그 정도면 우형글만 봐라 - dc App