Programming/Spring

[SpringBoot] @Transactional로 트랜잭션이 적용되는 원리

코딩하는 포메라니안 2023. 5. 6. 00:12

💡궁금하게 된 계기

하나의 클래스 안에서, @Transactional이 없는 메서드에서 있는 메서드를 호출할 때 트랜잭션이 적용되지 않는다는 것을 알았다. 이 문제로 부터, 궁금한 것을 이어가다보니 트랜잭션 어노테이션의 동작 방식에 대해 조사하게 되었다.

 

✅ 필요한 사전 지식

2023.03.21 - [CS/디자인패턴] - Proxy Pattern | 프록시 패턴

2023.03.22 - [Programming/Spring] - [SpringBoot] 관점 지향 프로그래밍 AOP의 개념과 사용법

 

 

@Transactional이 적용되는 과정 간단하게 보기

Spring Boot의 @Transactional은 AOP와 Proxy를 기반으로 동작한다.

정확히는, @Transactional은 AOP를 이용하고, AOP는 Proxy패턴을 생성해서 처리하는 것이다.

Proxy패턴을 만드는 방법은 JDK Proxy와 CGLib Proxy로 나뉘는데, Spring에서는 JDK Proxy를 Spring Boot에서는 CGLib Proxy를 기본으로 한다.

 

여기서는 CGLib Proxy에 집중해보려고 한다.

CGLib Proxy는 간단하게 말하면, 코드를 조작해서 프록시 객체를 만드는 것을 말한다.

아래 예시는 본 코드와는 조금 다르겠지만, 조작해서 프록시 객체를 만드는 대략적인 방법을 이해하기 위해 작성해보았다.

개발자가 작성한 코드

public class MyService{

    private final InfoRepository infoRepository;

    public Info getInfo(){
        return infoRepository.get();
    }
    
    @Transactional
    public void save(Info info){
    	infoRepository.save(info);
    }
}

 

Proxy로 조작된 프록시 객체

구현한 코드 앞뒤로 필요한 코드를 삽입되었다. 

public class MyServiceProxy extends MyService{

    private final TransactonManager manager = TransactionManager.getInstance();
    
    public void save(Info info){
    	try{
            manager.begin();
            super.save(info);
            manager.commit();
        } catch(Exception e){
            manager.rollback();
        }
    	
    }
}

 

🚀 결론

- SpringBoot의 @Transactional은 AOP를 이용함

- SpringBoot의 AOP는 Proxy패턴을 생성해서 처리함.

- AOP는 외부 클래스에서 불릴 때, 적용되기 때문에, 같은 클래스 내부에서 부르면 적용이 안된다.

*같은 클래스 내부에서 @Transactional이 적용된 메서드에서 또 다른 내부 메서드를 부를 때는 기본적으로 먼저 호출된 메서드에 의해 적용된다. 이는 트랜잭션 전파에 대해서 학습해보면, 더 다양한 케이스를 확인할 수 있다.

 

 

+) 여기서, 실제로 Proxy객체가 언제 어떻게 생성되고 동작하는지 알고 싶어서 코드를 통해 알아보았는데, 글을 정리하여 올릴 예정이다.