- Today
- Yesterday
- Total
메이쁘
[Spring] 예상 Q&A 공부(Transactional 트랜잭션 적용 범위) 본문
안녕하세요.
CS관련 질문과 면접에 맞는 답변을 작성하면서 지식도 쌓고 면접도 대비하는 시간을 가지려고 합니다.
틈틈히 게시글을 작성하며 면접 대비 데이터셋을 확보해둔 다음
언젠간 면접하게 될 때 모아서 쓰려고 합니다.
(실제로 면접에서 들었던 질문이 아니라, 제가 스스로 답을 정해놓고 짜논 질문이라 이렇게 안나올 수 있습니다!!!)
이번 글은 Spring 카테고리 입니다.
-- 질문 목록
Q1. 상위 메소드에서 @Transactional 어노테이션을 적용하지 않고, 하위 메소드에서만 적용했을 때, 상위 메소드에서 하위 메소드 호출 시 Transaction이 반영되지 않는 이유는?
Q2. 그럼, 상위 메소드 및 하위 메소드 둘 다 @Transactional 어노테이션을 적용했을 때, 트랜잭션이 어떻게 동작할까요?
Q3. @Transactional 어노테이션을 추가해도 트랜잭션이 적용되지 않는 경우는 무엇이 있을까요?
Q1. 상위 메소드에서 @Transactional 어노테이션을 적용하지 않고, 하위 메소드에서만 적용했을 때, 상위 메소드에서 하위 메소드 호출 시 Transaction이 반영되지 않는 이유는?
A. 트랜잭션은 Proxy 기반으로 동작하며, AOP로 구성되어 있기 때문에 트랜잭션 어노테이션이 있는 다른 내부 메소드를 호출해도 트랜잭션이 동작하지 않습니다. 이는 곧 메소드가 실행되기 전/후로 자동으로 트랜잭션을 묶습니다. 즉, Spring에서는 빈 인스턴스(인터페이스 기반)에서 처음 호출하는 메소드나 클래스의 속성을 따라가기 때문에 상위 메소드에 @Transactional 어노테이션이 존재하지 않으면 존재하지 않은 채로 어떤 로직을 수행하던지 간에 메소드 종료 시 까지 트랜잭션이 적용되지 않게 됩니다.
Q2. 그럼, 상위 메소드 및 하위 메소드 둘 다 @Transactional 어노테이션을 적용했을 때, 트랜잭션이 어떻게 동작할까요?
A. 위와 마찬가지로, 상위 메소드만 트랜잭션이 적용되고, 하위 메소드의 트랜잭션은 무시됩니다. 하위 메소드에 @Transactional 어노테이션이 존재하더라도 새로운 트랜잭션이 생성되는 것이 아니라 상위 메소드의 트랜잭션에 참여하게 됩니다. 이는 @Transactional 어노테이션의 propagation(전파 레벨)의 default 속성이 REQUIRED인데, 이것은 기존 트랜잭션이 존재하는 경우는 해당 트랜잭션에 참여하고, 존재하지 않을 땐 새로운 트랜잭션을 생성해서 진행하는 속성입니다. 그렇기 때문에, 하위 메소드에서 전파 레벨을 변경하지 않는 한 상위 메소드의 트랜잭션에 따라가게 됩니다.
*** 대신, Q3의 답변처럼 Self Injection을 통한 내부 메소드 호출 시의 얘기이고, Self Injection이 아닌 경우 AOP 특성 상 내부 메소드는 트랜잭션이 적용되지 않습니다.
Q3. @Transactional 어노테이션을 추가해도 트랜잭션이 적용되지 않는 경우는 무엇이 있을까요?
A. 우선, 첫 번째로 public 함수가 아닌 private 함수에 적용한 경우가 있습니다. 메소드가 public 접근일 경우에만 트랜잭션이 적용됩니다.
다음으로, 상위 함수에 @Transactional 어노테이션이 추가되어 있지 않은 경우, @Transactional 어노테이션이 추가된 하위 함수를 호출해도 트랜잭션이 실행되지 않습니다.
이를 해결하기 위해서는 상위 함수에 어노테이션을 추가하거나, 인터페이스 기반의 새로운 Bean instance를 만들어 활용하는 Bean 및 Class 분리 방법과 Self Injection을 통해 자기 자신의 빈 인스턴스를 활용하는 방법이 있습니다.
(잘 모르지만) 또, 별도의 Transaction Handler class를 만들어 사용하는 방법도 있습니다.
class TransactionHandler {
@Transactional
public <T> T execute(Supplier<T> supplier) {
return supplier.get();
}
}
public void transaction() {
transactionHandler.execute(() -> this.foo());
}
이상입니다.
감사합니다.
'면접 대비 CS지식 > SELF CS면접 Q&A' 카테고리의 다른 글
[Spring] 예상 Q&A 공부(EntityManager, 영속성 컨텍스트, @Transactional readOnly) (0) | 2021.12.29 |
---|---|
[Spring] 예상 Q&A 공부(Entity @Setter 지양 이유, @ControllerAdvice 관련) (0) | 2021.12.28 |
[WEB] 예상 Q&A 공부(HTTP Status Code, Web과 WAS의 차이) (0) | 2021.03.02 |
[Android] 2021.01.28. 오늘의 면접 Q&A (0) | 2021.01.28 |
[Network] 2020.12.04. 오늘의 면접 Q&A (0) | 2020.12.04 |