@Transactional
@Slf4j
static class CallService {
//메서드 내부호출에서는 this.internal이 실행되므로 Transactional이 적용되지않는다.
// 적용하려면 별도의 클래스로 분리하여야한다.
public void external() {
log.info("call external");
printTxInfo();
internal();
}
@Transactional
public void internal() {
log.info("call internal");
printTxInfo();
}
private void printTxInfo() {
boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
log.info("tx active={}", txActive);
}
}
————>>>>————>>>>————>>>>————>>>>————>>>>————>>>>————>>>>————>>>>————>>>>
@Slf4j
@RequiredArgsConstructor
static class CallService {
//메서드 내부호출에서는 this.internal이 실행되므로 Transactional이 적용되지않는다.
// 적용하려면 별도의 클래스로 분리하여야한다.
private final InternalService internalService;
public void external() {
log.info("call external");
printTxInfo();
internalService.internal();
}
// @Transactional
// public void internal() {
// log.info("call internal");
// printTxInfo();
// }
private void printTxInfo() {
boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
log.info("tx active={}", txActive);
}
}
@Slf4j
static class InternalService {
@Transactional
public void internal() {
log.info("call internal");
printTxInfo();
}
private void printTxInfo() {
boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
log.info("tx active={}", txActive);
}
}
public 메서드만 트랜잭션 적용
스프링의 트랜잭션 AOP 기능은 public 메서드에만 트랜잭션을 적용하도록 기본 설정이 되어있다.
참고로 public 이 아닌곳에 @Transactional 이 붙어 있으면 예외가 발생하지는 않고, 트랜잭션 적용만 무시된다.
스프링 초기화 시점에는 트랜잭션 AOP가 적용되지 않을 수 있다.
왜냐하면 초기화 코드가 먼저 호출되고, 그 다음에 트랜잭션 AOP가 적용되기 때문이다.
따라서 초기화 시점에는 해당 메서드에서 트랜잭션을 획득할 수 없다.
가장 확실한 대안은 ApplicationReadyEvent 이벤트를 사용하는 것이다.
@EventListener(value = ApplicationReadyEvent.class)
@Transactional
public void init2() {
log.info("Hello init ApplicationReadyEvent");
}
----
언체크 예외는 롤백한다.
체크예외는 커밋한다.
예외 발생시 스프링 트랜잭션 AOP는 예외의 종류에 따라 트랜잭션을 커밋하거나 롤백한다.
언체크 예외인 RuntimeException , Error 와 그 하위 예외가 발생하면 트랜잭션을 롤백한다.
체크 예외인 Exception 과 그 하위 예외가 발생하면 트랜잭션을 커밋한다.
물론 정상 응답(리턴)하면 트랜잭션을 커밋한다.
'SpringFramework | SpringBoot' 카테고리의 다른 글
스프링에서 어디서나 HttpServletRequest 얻는방법 (0) | 2023.11.10 |
---|---|
스프링의 기본 동작원리 (0) | 2023.11.10 |
spring 뷰 선택 우선 순위 (0) | 2023.11.10 |
[Mybatis] useGeneratedKeys와 selectKey (0) | 2023.11.09 |
SpringBoot의 메인 메서드의 풀이 (0) | 2023.11.09 |