
프록시 내부 호출 해결
- 메서드 내부 호출 때문에 트랜잭션 프록시가 적용되지 않는 문제를 해결하기 위해 해당 메서드를 별도의 클래스로 분리하여 해결한다
- 다른 방법들도 있지만 주로 이 방법으로 해결함(편하기 때문임)
예)
@Slf4j
@SpringBootTest
public class InternalCallV2Test {
@Autowired
CallService callService;
@Test
void printProxy() {
log.info("call service={}", callService.getClass());
}
@Test
void externalCall() {
callService.external();
}
@TestConfiguration
static class InternalCallV1TestConfig {
@Bean
CallService callService() {
return new CallService(internalService());
}
@Bean
InternalService internalService() {
return new InternalService();
}
}
@Slf4j
@RequiredArgsConstructor
static class CallService {
private final InternalService internalService;
public void external() {
log.info("call external");
printTxInfo();
internalService.internal();
}
private void printTxInfo() {
boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
log.info("tx active={}", txActive);
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
log.info("tx readOnly={}", readOnly);
}
}
static class InternalService {
@Transactional
public void internal() {
log.info("call internal");
printTxInfo();
}
private void printTxInfo() {
boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
log.info("tx active={}", txActive);
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
log.info("tx readOnly={}", readOnly);
}
}
}

- 동작
- 클라이언트인 테스트 코드는
callService.external() 을 호출한다.
callService 는 실제 callService 객체 인스턴스이다.
callService 는 주입 받은 internalService.internal() 을 호출한다.
internalService 는 트랜잭션 프록시이다. internal() 메서드에 @Transactional 이 붙어 있으 므로 트랜잭션 프록시는 트랜잭션을 적용한다.
- 트랜잭션 적용 후 실제
internalService 객체 인스턴스의 internal() 을 호출한다.
public 메서드
- 스프링의 트랜잭션 AOP 기능은
public 메서드에만 트랜잭션을 적용하도록 기본 설정이 되어있다(스프링 3.0 부터는 protected , package-visible (default 접근제한자) 적용됨)
- 이렇게 클래스 레벨에 트랜잭션을 적용하면 모든 메서드에 트랜잭션이 걸릴 수 있다. 그러면 트랜잭션을 의도하지 않는 곳 까지 트랜잭션이 과도하게 적용된다. 트랜잭션은 주로 비즈니스 로직의 시작점에 걸기 때문에 대부분 외부에 열어준 곳을 시작점으로 사용한다. 이런 이유로
public 메서드에만 트랜잭션을 적용하도록 설정되어 있다