Spring/Transaction 9

트랜잭션 전파

@Transactional과 REQUIRED 트랜잭션 전파의 기본 값은 REQUIRED 이다. 따라서 다음 둘은 같다. @Transactional(propagation = Propagation.REQUIRED) @Transactional REQUIRED 는 기존 트랜잭션이 없으면 새로운 트랜잭션을 만들고, 기존 트랜잭션이 있으면 참여한다. 트랜잭션 전파 위 그림과 같이 MemberService, MemberRepository, LogRepository 가 하나의 트랜잭션의 묶여있는 상황을 가정해보자 public class MemberService { private final MemberRepository memberRepository; private final LogRepository repository..

Spring/Transaction 2023.09.05

Spring Transaction AOP 주의사항 - 초기화 시점

스프링 초기화 시점에는 트랜잭션 AOP가 적용되지 않을 수 있다. import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context...

Spring/Transaction 2023.08.15

Spring Transaction AOP 주의사항 - 프록시 내부호출 문제해결

이전글 (https://hwanguu.tistory.com/6) 메서드 내부 호출 때문에 트랜잭션 프록시가 적용되지 않는 문제를 해결하기 위해 CallService의 internal() 메서드를 별도의 클래스로 분리하자. import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.conte..

Spring/Transaction 2023.08.15

Spring Transaction AOP 주의사항 - 프록시 내부호출 문제

@Transactional 을 사용하면 스프링의 트랜잭션 AOP가 적용된다. 트랜잭션 AOP는 기본적으로 프록시 방식의 AOP를 사용한다. 앞서 배운 것 처럼 @Transactional 을 적용하면 프록시 객체가 요청을 먼저 받아서 트랜잭션을 처리하고, 실제 객체를 호출해준다. 따라서 트랜잭션을 적용하려면 항상 프록시를 통해서 대상 객체(Target)을 호출해야 한다. 이렇게 해야 프록시에서 먼저 트랜잭션을 적용하고, 이후에 대상 객체를 호출하게 된다. 만약 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 AOP가 적용되지 않고, 트랜잭션도 적용되지 않는다. 아래 그림에서 internal()에서 external()을 바로 호출하는 경우에 해당한다. AOP를 적용하면 스프링은 대상 객체 대신에 프록시..

Spring/Transaction 2023.08.15

Spring Transaction 우선순위

스프링에서 우선순위는 항상 더 구체적이고 자세한 것이 높은 우선순위를 가진다. 이것만 기억하면 스프링에서 발생하는 대부분의 우선순위를 쉽게 기억할 수 있다. 그리고 더 구체적인 것이 더 높은 우선순위를 가지는 것은 상식적으로 자연스럽다. 예를 들어서 메서드와 클래스에 애노테이션을 붙일 수 있다면 더 구체적인 메서드가 더 높은 우선순위를 가진다. 인터페이스와 해당 인터페이스를 구현한 클래스에 애노테이션을 붙일 수 있다면 더 구체적인 클래스가 더 높은 우선순위를 가진다. 클래스 메서드( 1 ) > 클래스 ( 2 ) > 인터페이스 메서드 ( 3 ) > 인터페이스 ( 4 ) 위와 같이 자세할수록 우선순위가 높아진다. 아래의 코드로 확인하자 (@Transactional 의 위치를 유심히 보자!) 우선순위 1. (..

Spring/Transaction 2023.08.15

Spring Transaction 적용

트랜잭션 적용 확인 @Transactional 을 통해 선언적 트랜잭션 방식을 사용하면 단순히 애노테이션 하나로 트랜잭션을 적용할 수 있다. 그런데 이 기능은 트랜잭션 관련 코드가 눈에 보이지 않고, AOP를 기반으로 동작하기 때문에, 실제 트랜잭션이 적용되고 있는지 아닌지를 확인하기가 어렵다. 아래 코드를 확인하여 트랜잭션이 실제 적용되는지 확인해보자. import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory..

Spring/Transaction 2023.08.15

Spring Transaction 과 AOP

@Transactional 기본적으로 트랜잭션을 사용할때는 @Transactional 이라는 애노테이션을 사용한다. @Transactional 을 통한 선언적 트랜잭션 관리 방식을 사용하게 되면 기본적으로 프록시 방식의 AOP가 적용된다. 프록시 란? 프록시의 사전적 정의는 '대리인'으로, 간단하게 설명하면 내가 어떤 객체를 사용하려고 할 때 해당 객체에 직접 요청하는 것이 아닌 중간에 가짜 프록시 객체(대리인)를 두어서 프록시 객체가 대신해서 요청을 받아 실제 객체를 호출해 주도록 하는 것이다. 프록시 모드를 설정하게 되면, 의존성 주입을 통해 주입되는 빈은 실제 빈이 아닌 해당 빈을 상속받은 가짜 프록시 객체이다. 스프링은 CGLIB이라는 바이트 코드를 조작하는 라이브러리를 사용해서 프록시 객체를 주..

Spring/Transaction 2023.08.15

Spring Transaction 이란?

Transaction 이란? 만약 데이터베이스의 데이터를 수정하는 도중에 예외가 발생된다면 어떻게 해야 할까? DB의 데이터들은 수정이 되기 전의 상태로 다시 되돌아가져야 하고, 다시 수정 작업이 진행되어야 할 것이다. 이렇듯 여러 작업을 진행하다가 문제가 생겼을 경우 이전 상태로 롤백하기 위해 사용되는 것이 트랜잭션(Transaction) 이다. 트랜잭션은 더 이상 쪼갤 수 없는 최소 작업 단위를 의미한다. 그래서 트랜잭션은 commit으로 성공 하거나 rollback으로 실패 이후 취소되어야 한다. 하지만 모든 트랜잭션이 동일한 것은 아니고 속성에 따라 동작 방식을 다르게 해줄 수 있다. 예를 들어 1개의 새로운 데이터를 추가하는 와중에 에러가 발생하면 해당 추가 작업은 없었던 것처럼 되돌려진다. 하..

Spring/Transaction 2023.08.15