횡단 관심사에 대해 인터페이스와 DI를 통해 무엇을 하는지 비즈니스 로직에 남기고, 그들의 역할을 따로 분리하여 비즈니스 로직에 영향을 미치지 않고 독립적인 변경을 할 수 있게 도와주는것
예) 모든 비즈니스 로직에 적용된 트랜잭션
❗프록시를 통해 비즈니스 코드에서 트랜잭션 적용 코드는 제거했지만 이를 적용할 다른 비즈니스 로직에 모두 적용할려면 프로그래머가 프록시객체를 생성해야했다.
→ 프록시 클래스 없이도 프록시 오브젝트를 런타임시 만들어주는 다이나믹 프록시 기술 적용
❗프록시 클래스를 직접생성하는 불편함은 제거되었지만, 동일한 역할을 하는 프록시때문에 오브젝트 단위로 중복이 발생한다.
→ 스프링에서는 프록시 기술을 추상화 한 프록시 팩토리 빈을 적용하여 다이나믹 프록시에 DI를 적용하였다. DI를 적용하여 오브젝트 단위 중복 제거
→ 스프링의 프록시 팩토리 빈은 내부적으로 템플릿-콜백패턴을 통해 추상화 시 아래 내용도 따로 분리할 수 있었다. 이로인해 여러 프록시에서 공유해서 사용가능해짐
❗프록시 적용대상 빈마다 일일이 프록시 팩토리 빈을 설정해야한다는 번거로움
→ 스프링 컨테이너의 빈생성 후처리 기법을 활용하여 스프링 컨테이너가 초기화 될때 자동으로 프록시가 생성되도록 하였다. 프록시를 적용할 대상은 지정대상에 대한 패턴을 이용
전통적인 객체지향 설계 방법으로 독립적인 구현이 힘든 트랜잭션 경계설정과 같은 모듈은 오브젝트가 아닌 Aspect라고 칭한다.
어플리케이션의 핵심 기능은 아니지만, 부가기능으로써 중요한 기능을 하고 있다.
프록시를 사용하지않는 AOP 프레임워크
컴파일된 타깃의 클래스 파일 자체를 수정하거나 클래스가 JVM에 로딩되는 시점에 가로채서 바이트 코드를 조작한다.
❓그럼 왜 이런 복잡한 방식을 사용하나?
바이트 코드를 조작하면 스프링과같은 DI 컨테이너의 도움을 받지 않고 쉽게 AOP적용
프록시 방식보다 강력하고 유연하다. 부가기능 부여대상은 클라이언트가 호출하는 메서드로 제한적
바이트코드를 조작하면 오브젝트 생성, 필드값의 조회, 수정, static 초기화 시에도 조작이 가능하다.
트랜잭션의 경계에서 이미 진행중인 트랜잭션이 있을때와 없을때 어떻게 동작할지 결정하는 방식

→ 트랜잭션 시작 시 getTransaction()을 통해 Transaction객체를 얻는 이유
먼저 생성된 트랜잭션으로 부터 트랜잭션을 얻을 수도 있고, 새로운 트랜잭션 객체를 생성하기도 하기 때문
Transaction getTransaction() throws SystemException
Get the transaction object that represents the transaction context of the calling thread.
서버환경에서 여러개의 트랜잭션 동시 진행 시, 격리 수준을 통해 동시에 진행되어도 문제가 발생하지 않도록 하는 설정
기본적으로는 DB에 설정되어 있지만, 트랜잭션 단위로 설정할 수 도 있다.
특별한 경우가 아니라면 DB설정을 따르는게 좋다.
트랜잭션을 수행하는 제한시간
default는 제한 시간이 없다.
[참고]
https://www.javainuse.com/spring/boot-transaction-propagation