@Transactional 은 어느 Layer 에 두는게 맞을까?

Dope
Webdev TechBlog
Published in
4 min readAug 31, 2021

서론

회사에서 스프링을 사용하여 개발을 하고 있던 와중에 문득 @Transactional 어노테이션이 눈에 들어왔으며, repository interface, service, service impl 이렇게 3군데에서 개발자마다 각각 다르게 사용 중이 었습니다. 트랜잭션 기능을 지원하는 @Transactional 어노테이션이 어느 Layer 에 있어야 하는게 맞는건지 찾아보고 공부한 내용을 공유해드리고자 합니다.

@Transactional 의 적절한 위치는 세부 구현체

Spring Docs 의 Tip 부분에 다음과 같이 명확하게 나와있습니다.

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class=”true”) or the weaving-based aspect (mode=”aspectj”), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

Spring은 인터페이스에 주석을 추가하는 대신 @Transactional 주석으로 구체적인 클래스 (및 구체적인 클래스의 메서드)에만 주석을 달도록 권장합니다. 인터페이스 (또는 인터페이스 메소드)에 @Transactional 어노테이션을 배치 할 수 있지만 이는 인터페이스 기반 프록시를 사용하는 경우 예상 한 대로만 작동합니다. Java 주석이 인터페이스에서 상속되지 않는다는 사실은 클래스 기반 프록시 (proxy-target-class = “true”) 또는 위빙 기반 측면 (mode = “aspectj”)을 사용하는 경우 트랜잭션 설정이 다음과 같음을 의미합니다. 프록시 및 위빙 인프라에 의해 인식되지 않으며 객체가 트랜잭션 프록시에 래핑되지 않으므로 확실히 나쁠 것입니다.

보통 개발을 하게되면 하나의 서비스 등록 메서드 안에서 여러개의 서비스 의존성을 받아서 동시에 등록하는 경우가 상당히 많습니다. 따라서 구현체에 트랜잭션 설정을 하는 것이 좋다고 생각합니다.

참고

--

--

Dope
Webdev TechBlog

Developer who is trying to become a clean coder.