언체크 예외 발생 시 예외 처리를 했는데도 RollBack 이 되어 데이터베이스에 반영이 안되고 체크 예외 발생 시 예외 처리를 하고 결과를 보면 Commit이 되어 데이터베이스에 반영이 된다. 이게 어떻게 동작하는 걸까?
동작을 알아보기 전에 먼저 언체크 예외와 체크 예외에 대해 개념을 살펴보자.
언체크 예외는 RuntimeException 클래스를 상속한 예외를 말한다. 컴파일러가 에러 난 부분을 체크 하여 알려주지 않아 언체크 예외라고 생각하면 될 것이다.
체크 예외는 언체크 예외를 제외한 예외를 말한다. 컴파일러가 체크를 한 예외여서 체크 예외라고 생각하면 된다.
언체크, 체크 개념을 알아보았으니 트랜잭션 단위에서 예외 처리를 진행해 커밋과 롤백의 동작을 테스트 해보자.
예외를 던지다
@Transactional
@Test
void MemberServiceTest() {
try {
Team team = Team.builder()
.name("kk")
.build();
teamRepository.save(team);
Member member = Member.builder()
.team(team)
.name("kb")
.build();
memberRepository.save(member);
throw new RuntimeException("오류났다!! RollBack 된다!!");
} catch (RuntimeException e) {
e.printStackTrace();
System.out.println("오류 메시지 !! " + e.getMessage());
}
}
위 코드는 Team 엔티티와 Member 엔티티의 데이터 값을 저장하고 RuntimeException 을 던지며 RuntimeException 의 예외 처리를 하는 코드이다.
코드의 실행 결과는 RuntimeException이 발생하고 RollBack이 진행 되었다.
디버깅을 하여 확인해보자.
TransactionAspectSupport 의 클래스의 invokeWithinTransaction() 메서드에서 예외를 잡는다.
Throwable 은 Exception 클래스의 상위 클래스이다.
RuntimeException 은 Exception 클래스를 상속하고 있으므로 catch문에서 처리가 된다.
completeTransactionAfterThrowing() 메서드에서 예외를 파라미터값으로 넘겨 조건문을 진행한다.
조건문을 타고 rollbackOn() 메서드에 의해 예외 타입을 체크하고 타입에 맞게 RollBack 이 진행되게 된다.
언체크 예외 처리 동작 방식을 살펴보았는데 체크 방식도 동작 방식이 비슷한데 결과는 RollBack 진행이 안되고 Commit 이 된다. Commit 을 하지 않고 RollBack을 하고 싶다면 @Transactional(rollbackOn = "체크 예외 클래스") 를 사용하면 된다.
'JPA' 카테고리의 다른 글
[Jpa] Transaction Scope and Isolation (0) | 2022.08.05 |
---|---|
[Jpa] Deprecated 된 getById() 대안 getReferenceById() (0) | 2022.08.02 |
[Jpa] Dirty Checking (0) | 2022.07.19 |
[Jpa] Projections (0) | 2022.07.18 |
[Spring JPA] CASCADE 는 무엇일까? (0) | 2022.05.15 |
[Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까? (0) | 2022.05.15 |
[Spring JPA] 프록시 객체는 어떻게 동작할까? (0) | 2022.05.12 |
[Spring JPA] 객체지향의 상속관계 매핑은 어떤 전략을 사용할까? (0) | 2022.05.12 |