@Transactional은 Spring AOP와 프록시를 기반으로 트랜잭션을 처리합니다.

Spring은 @Transactional이 적용된 빈을 등록할 때 해당 빈의 프록시 객체를 생성합니다.
외부에서 메서드를 호출하면 실제 객체가 아닌 프록시가 먼저 호출을 가로챕니다.

프록시는 TransactionManager를 통해 트랜잭션을 시작하고, 실제 대상 메서드를 호출합니다.
메서드가 정상적으로 종료되면 트랜잭션을 커밋하고, 예외가 발생하면 롤백 여부를 판단하여 롤백합니다.
기본적으로 RuntimeException과 Error가 발생하면 롤백하지만, 체크 예외는 롤백하지 않습니다.

JPA 환경에서는 일반적으로 JpaTransactionManager가 현재 스레드에 EntityManager를 연결하고, 같은 트랜잭션 안에서 수행되는 작업들이 동일한 영속성 컨텍스트를 사용하도록 관리합니다. 트랜잭션이 커밋될 때 변경 감지와 플러시가 수행되고, 이후 실제 데이터베이스 트랜잭션이 커밋됩니다.

따라서 @Transactional은 단순히 커밋과 롤백을 수행하는 어노테이션이 아니라, 프록시와 AOP를 이용해 트랜잭션의 시작과 종료, 전파, 격리 수준, 롤백 정책 등을 선언적으로 관리하는 기능입니다.

주의할 점은 프록시를 거쳐야 동작한다는 것입니다. 같은 클래스 내부에서 this로 메서드를 호출하는 자기 호출은 프록시를 거치지 않으므로, 호출되는 메서드의 @Transactional 설정이 별도로 적용되지 않습니다.