728x90
커밋, 롤백
@Transactional과 REQUIRED
- REQUIRED 는 기존 트랜잭션이 없으면 새로운 트랜잭션을 만들고, 기존 트랜잭션이 있으면 참여한다.
- @Transactional(propagation = Propagation.REQUIRED) == @Transactional
서비스 계층에 트랜잭션이 없을 때 - 롤백

- 이 경우 회원은 저장되지만, 회원 이력 로그는 롤백된다. 따라서 데이터 정합성에 문제가 발생
- 둘을 하나의 트랜잭션으로 묶어서 처리해보자.
단일 트랜잭션


각각 트랜잭션이 필요한 상황
- Repository & Service 모두 트랜잭션이 필요한 경우

- 클라이언트 A : MemberService 에 트랜잭션을 남기고, MemberRepository , LogRepository 의 트랜잭션 코드를 제거해야함.
- 그렇게 되면 클라이언트 B, C가 호출하는 MemberRepository , LogRepository 에는 트랜잭션을 적용할 수 없다.

- 클라이언트 Z가 호출하는 OrderService 에서도 트랜잭션을 시작할 수 있어야 하고,
- 클라이언트A가 호출하는 MemberService 에서도 트랜잭션을 시작할 수 있어야 한다.
전파 커밋



전파 롤백

복구 REQUIRED
◎ 요구 사항 : 회원 가입을 시도한 로그를 남기는데 실패하더라도 회원 가입은 유지되어야 한다.
즉, MemberRepository 논리 트랜잭션은 커밋, LogRepository 논리 트랜잭션은 롤백, 전체 물리 트랜잭션은 커밋.


★ 정리
- 논리 트랜잭션 중 하나라도 롤백되면 전체 트랜잭션은 롤백된다.
- 내부 트랜잭션이 롤백 되었는데, 외부 트랜잭션이 커밋되면 UnexpectedRollbackException 예외가 발생한다.
- rollbackOnly 상황에서 커밋이 발생하면 UnexpectedRollbackException 예외가 발생한다
복구 REQUIRES_NEW
◎ 요구 사항 : 회원 가입을 시도한 로그를 남기는데 실패하더라도 회원 가입은 유지되어야 한다.
LogRepository - save() : 항상 신규 트랜잭션 생성
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Log logMessage)

- REQUIRES_NEW 를 사용하게 되면 물리 트랜잭션 자체가 완전히 분리되어 버린다.
- 그리고 REQUIRES_NEW 는 신규 트랜잭션이므로 rollbackOnly 표시가 되지 않는다.

★ 정리
- 논리 트랜잭션은 하나라도 롤백되면 관련된 물리 트랜잭션은 롤백되어 버린다.
- REQUIRES_NEW 를 사용해서 트랜잭션을 분리해야 한다.
☆ 주의
- REQUIRES_NEW 를 사용하면 하나의 HTTP 요청에 동시에 2개의 데이터베이스 커넥션을 사용하게 된다.
- 성능이 중요한 곳에서는 이런 부분을 주의해서 사용해야 한다.

반응형
'Spring > DB 2편' 카테고리의 다른 글
스프링 트랜잭션 전파1 - 기본 (0) | 2023.08.11 |
---|---|
스프링 트랜잭션 이해 (0) | 2023.08.11 |
데이터 접근 기술 - 활용 방안 (0) | 2023.08.11 |
데이터 접근 기술 - Querydsl (0) | 2023.08.11 |
데이터 접근 기술 - 스프링 데이터 JPA (0) | 2023.08.11 |