• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

BookService의 saveBook()의 @Trnasacional 궁금합니다.

22.09.13 23:11 작성 조회수 189

1

BookService의 saveBook()의 @Transacional 이 붙는 이유가 궁금합니다.

repository.save() 자체에도 @Transacional 이 있는데요-

saveBook() 에도 붙이신 이유가 있을까요?

그리고 BookEntity는 아무 연관관계도 없어서 영향이 없을것 같아서요.

답변 1

답변을 작성해보세요.

4

안녕하세요 지민님!!! 크으~~ 아주 날카롭고 좋은 질문이십니다!!! ㅎㅎㅎㅎ

그렇죠~ 말씀해주신것처럼 SimpleJpaRepository.java의 CRUD 메소드에는 @Transactional이 잘 붙어 있어 사실 해당 메소드만 놓고 보면 딱히 필요하지 않습니다!

하지만 저는 아래 3가지 이유로, Service 단에 @Transactional을 꼭 붙여주는 편입니다!! (강조드리지만 정답이 있는 문제라고 생각하지 않습니다!!!)

  1. 명시적인 설정과 암시적인 설정

    1. SimpleJpaRepository에 존재하는 트랜잭션은 비즈니스 로직을 개발하는 개발자에게 일종의(?) 암시적인 설정입니다! 이를 Service 단에 명시적으로 적어주는 것이 여러 개발자와 협업할 때 도움이 되더라고요! 항상 스프링에 익숙한 개발자와 협업하지는 않으니까요!

  2. 통일성 측면

    1. 사실 @Transactional을 붙이지 않아도 되는 경우는 saveBook 처럼 매우 간단한 경우만 해당됩니다! 대부분은 이보다 복잡한 로직을 가지고 있고 query도 여러번 나가니 트랜잭션이 필요하죠! 그래서 간단한 기능이더라도 다른 Service method와의 통일성을 위해 어노테이션을 표기해주는 것을 선호합니다!

  3. Service와 Repository의 R&R

    1. 저는 개인적으로 트랜잭션 처리를 Service의 역할이라고 생각합니다! 상황에 따라서는 Controller에서 진입하는 최초 Service (ApplicationService)는 트랜잭션을 붙이지 않고 최초 Service가 호출하는 Service (DomainService)에 트랜잭션을 붙여 처리하기도 하지만, Repository에서 트랜잭션을 열고 닫기보다는 Service에서 처리해주는 것이 바람직한 것 같아요!

 

그렇다면~ 추가로 왜 Controller 단에 붙이지 않고 Method 단에 각각 붙였는지도 말씀드려 보자면, Kotlin에서 trailing comma를 도입한 이유와 비슷합니다! - https://www.inflearn.com/questions/620662

혹시나 서비스 로직의 변경으로 인해 readOnly 옵션을 붙여주거나 제거해야 하는 경우, 그 변경 여파를 해당 메소드에 달려 있는 어노테이션으로만 국한하기 위해서에요!!

 

예를 들어, 다음과 같이 간단한 수도 코드를 생각해보겠습니다!

@Transactional
class Service {
  fun a()
  fun b()

  @Transactional(readOnly = true)
  fun c()
}

그런데 이제 a와 b모두 readOnly를 붙여도 되게 변경되었다면, 아예 클래스의 트랜잭션 어노테이션을 바꾸는게 나을지~ a와 b 위에 readOnly를 붙이는게 나을지~ 고민이 되기 시작합니다! 😢

저는 (개인적으로) 이런 고민을 할 바에 처음부터 메소드 단위로 트랜잭션을 붙여 고민 및 코드 변경 지점을 최소화 하는 것을 선호해서 메소드 단위로 붙였습니다! ㅎㅎㅎㅎ

 

제 답변이 도움이 되었으면 좋겠네요~!!

좋은 질문 남겨주셔서 감사드립니다!!! 🙏😊 편안한 밤 되세요~!