-
@Transactional 사용 시 주의해야 할 사항들스터디 노트 2023. 12. 4. 16:57
@Transactional 애너테이션은 스프링 AOP를 사용해 동작합니다.
AOP 위빙이 되지 않은 채 대상 메서드가 실행되어도 알기가 어렵습니다.
즉, 대상 메서드가 실행되었지만, 어드바이스가 정상적으로 실행되지 않을 수 있다는 말이 됩니다.
여기서 개발자가 쉽게 실수하는 두 가지 주의 사항과 사용할 때 유의점을 살펴보도록 하겠습니다.
✅ public 접근제어자로 선언된 메서드만 @Transactional 애너테이션이 동작합니다.
final이나 private 접근제어자로 선언된 메서드는 프록시로 만들 수 없기 때문에 애너테이션을 선언해도 정상동작하지 않습니다.✅ 스프링 빈으로 주입된 객체의 메서드를 호출해야 합니다.
당연하겠죠.우리는 스프링 프레임워크 위에서 동작하게 됩니다.
ApplicationContext가 어드바이스를 런타임에 위빙할 수 있단 말이죠.
스프링 빈에 있는 메서드들이 this키워드를 사용해 다른 메서드를 호출하면 어드바이스를 해당 메서드에 위빙할 수 없게 됩니다.this 키워드를 사용했으므로 개입 여지가 없기 때문이죠. 그러므로 자기주입 방식을 사용해 스프링 빈을 주입해야 합니다.
예를 들면 아래와 같은 상황인거죠.@Service public class XXXService { // ... public List<XXXCreateResponse> createXXX(List<XXXCreateRequest> createRequests) { return createRequests .stream() .map(createRequest -> this.createXXX(createRequest)) // Transaction 비정상 .collect(Collectors.toList()); } @Transactional(readOnly=false, isolation=Isolation.SERIALIZABLE) public XXXCreateResponse createXXX(XXXCreateRequest createRequest) { // ... } // ... }
✅ @Transactional의 설정 중 트랜잭션 격리 수준을 설정하는 isolation 속성은 통일하면 좋습니다.
격리수준에 따라 Dirty Read, Repeatable Read, Phantom Read 등의 상황이 발생해 API가 정상적으로 동작하지 않을 수가 있습니다. 만약 이 격리 수준이 자주 변경된다면 더 난감해지겠죠.위와 같은 사항들을 염두하여 @Transactional을 사용하면 문제 없이 트랜잭션 관리가 가능해질 것입니다 :D
'스터디 노트' 카테고리의 다른 글
Apache HttpClient 5 알아보기 (0) 2023.12.06 Optional, 그렇게 쓸꺼야🤔? (1) 2023.12.05 @Transactional 애너테이션에 대하여 (1) 2023.12.04 Java에서 Serializable은 무엇일까? 직렬화 vs 역직렬화 (1) 2023.12.04 Aspect Oriented Programming(AOP) 에 대하여 (0) 2023.11.23