-
@Transactional (1)Java&Spring/Spring 2023. 8. 9. 17:21
@Transactional 은 Aop 의 관점에서는 사용하기는 편리하지만 , 개발자가 동작원리를 이해를 기반으로 해야 효과적인
troubleshooting 이 가능하다 라고 생각한다.
학생 Id 를 이용하여 , 10 명의 학생 객체를 만들려고 한다.
식별자는 db 에서 생성을 받는다하자.
다음 코드가 동작을 정상적으로 할까 ?
@Service public class SomeService { @Transactional public void methodA(int studentId) { Student member = new Student(studentId) } @Transactional public void methodB() { for(int i = 0 ; i < 10 ;i++) { methodA(i) } } }
또는 ,
다음과 같이 서비스 레이어에서 트랜잭션이 걸려있는 메서드를 트랜잭션 어노테이션이 없는 메서드 B에서 호출을 한다.
어떤일이 일어 날까 ?
@Service public class SomeService { @Transactional public void methodA() { // ... } public void methodB() { // ... methodA(); // ... } }
두번째 질문의 답을 먼저한다 .
스프링에서의 @Transactional 어노테이션이 붙은 클라스의 메서드는 클라이언트에서 런타임시 직접적으로 호출이 되지 않고
프록시 객체를 통하여 호출이 된다. 이는 프록시 내부에서 내부를 호출시 Transaction 은 적용이 되지 않는다.
위의 이유로 우리는 Private 접근자로 @Transactional 을 선언을 할 수가 없다.
즉 @Transactional 가 없는 methodB 를 호출시 트랜잭션이 시작되지 않는다.
methodB에서 methodA 를 호출시 , Transaction 적용이 안된다.
이번에는 첫 번째 문제를 보자 ,
@Service public class SomeService { @Transactional public void methodA(int studentId) { Student member = new Student(studentId) } @Transactional public void methodB() { for(int i = 0 ; i < 10 ;i++) { methodA(i) } } }
methadA 에도 트랜젝션이 있으니 객체를 생성할 것 같지만 ,
같은 클라스에서 메서드의 호출에 따란 Transaction 의 중복은 의미가 없이 최초 Transaction 을 기준으로 동작한다.
즉 methodB 를 호출해도 데이터 베이스에서 10 명의 학생은 볼 수가 없다 , methodB 의 transactional 을 빼주자,
다음과 같이 서로 다른 클라스에서 메서드 각각 트랜 젝션이 걸려 있는 상태에서는 롤백이 어떻게 될까 ?
@Service public class TotalService { ... @Transactional public void methodB() { someService.methodA(); otherService.methodG(); myService.methodE(); } }
각 서비스 매서드 , 로컬 트랜잭션 3 개는 부모 트랜잭션인 methodB 의 트랜잭션의 합류하여 수행이된다.
즉 , 모두 같은 트랜잭션이 됨으로 어느 하나의 로직이 잘못되어 문제가 발생하면 전부 롤백 된다.
(트랜잭션 전파 수준에 따라 달라지며 위 설명은 기본 설정인 상황이다.)
참고 :
https://dev-coco.tistory.com/163
'Java&Spring > Spring' 카테고리의 다른 글
Spring 직렬화, dto 의 잘못된 이름의 함수가 있는 경우 (0) 2024.06.15 Spring vs Spring Boot (0) 2023.10.08 Q . SpringBoot 에서 경로를 어떻게 인식을 하는 것인가 ? part 1 (0) 2023.08.05 @RequiredArgsConsructor ,@NoArgsConstructor , @AllArgsConstructor (0) 2023.02.15 @RequiredArgsConstructor, @NotNull, @Valid ,@NotBlank (0) 2023.02.15