트랜잭션이 제대로 적용 안되는 문제,
그로 인하여 default인 오토커밋모드로 커밋되어 rollback을 해도 의도되로 안되는..
우선 다음 코드를 보자.
@Slf4j
@SpringBootTest
public class InternalCallV1Test {
@Autowired
CallService callService;
@Test
void printProxy(){
log.info("callService class={}", callService.getClass());
}
@Test
void internalCall(){
callService.internal();
}
@Test
void externalCall(){
callService.external();
}
@TestConfiguration
static class InternalCallV1TestConfig{
@Bean
CallService callService(){
return new CallService();
}
}
static class CallService{
public void external(){
log.info("call external");
internal();
}
@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);
}
}
}
externalCall()을 보면,
CallService의 external을 호출한다.
근데 external은 @Transactional이 아니며,
코드 내부에서는 @Transactional인 internal()을 호출하지만, 트랜잭션은 어느 곳에서도 시작되지 않는다.
그 이유는, @Transactional, 아니 프록시의 가로채는 방식에 있다.
@Test랑 똑같다. 그냥 그런 식으로 사용되도록 만들어 진 것이다.
@BeforeEach
public void before(){
log.info("before");
}
@Test
void check(){
proxyCheck();
proxyCheck();
}
@Test
void proxyCheck(){
log.info("aop class={}", basicService.getClass());
Assertions.assertThat(AopUtils.isAopProxy(basicService)).isTrue();
}
test에 이런 코드를 짜 봤는데,
check() 에서
@Test가 붙은 proxyCheck()를 2번이나 호출했지만,
before()은 한번만 호출되었다.
원래 @BeforeEach라는 것이, @Test 하기 전에 무조건 실행되는 건데,
@Test가 붙은 proxyCheck()를 2번이나 호출했지만 한번밖에 실행되지 않았다.
원래대로라면 @Test check() 한번, 그 후 proxyCheck() 두번 해서 총 3번 실행 되어야 한다.
하지만 한번만 호출 되는 것이 우리가 의도한 코드 그대로가 맞다는 것이다.
즉, 프록시도 저러 한 이유일 것이다.
그렇게 동작하도록 설계가 되었을 것이다.
프록시는 원래클래스를 상속받아 만든 것 이기 때문에, 원래 함수들을 다 자기 함수로 인식한다.
'스프링 > 6. 스프링 DB-2' 카테고리의 다른 글
44. 트랜잭션 AOP 주의사항 -초기화 시점 (0) | 2023.10.15 |
---|---|
43. 트랜잭션 AOP 주의사항 2 -프록시 내부호출 (0) | 2023.10.15 |
41. 스프링 트랜잭션 우선순위 (0) | 2023.10.14 |
40. 스프링 트랜잭션 테스트 (0) | 2023.10.14 |
39. DB 접근 기술의 조합 (0) | 2023.10.14 |