-
[JPA] Repository단에 Transactional을 선언하는 이유Spring Boot/JPA 2023. 10. 5. 22:37
Repository 적어도 일년 이상 궁금했던 의문이 풀려서 정리해본다.
Mybatis를 쓰다가 처음로 JPA를 실무에 도입을 할때,
위에 코드처럼 Repository단에 @Transcational를 선언하는 경우가 있었다.
Service단에 @Transcational을 선언하면 Spring이 AOP로 하나의 Transcation으로 전파되는데
왜 굳이 Repository에 선언해야할까?
Github에 유명하신 분들 코드를 뜯어봐도,
새로 이직한 회사의 코드를 뜯어봐도,
ChatGPT, 구글, 공식문서 다 찾아봤지만 알 수 없었는데... 드디어 알게 되었다.
Spring Boot Persistence Best Practice Spring Boot Persistence Best Practice 요약하면 Transaction이 너무 긴 Long Transaction이고 동시적인 요청을 받고 있을때 성능적으로 단점이 있기 때문이다.
스프링은 Transaction이 시작하는 그 즉시에 Database Connection Pool를 획득하고 실제 DB에 접근하지 않음에도 계속 CP를 가지고 있다고 한다. 때문에 Repository단에 Transactional을 선언해서 사용하면 실제 DB에 접근 할때 CP를 취득하고 반납할 수 있는 장점이 있다는 이야기
단, Repository단에서만 Transactional을 사용하면 ACID를 잃을 수 있다, 기본적으로 Repository에 Transactional을 선언해서 쓰더라도 필요에 따라 Service에 Transactional을 추가로 선언해서 사용해야한다.
Spring-Data-JPA 프로젝트를 뜯어보면 @Repository에 @Transactional을 선언해서 제작한 것을 알수 있다.
나도 모르게 Repository에서 @Transactional을 선언해서 사용하고 있었던 것Transactional 최적화 설정 - Transaction 경계 설정
참고 : https://pkgonan.github.io/2019/01/hibrnate-autocommit-tuning
Hibernate setAutoCommit 최적화를 통한 성능 튜닝
경험과 기억을 공유하다
pkgonan.github.io
- 위에 처럼 Repository에 Transactional을 선언하고
spring.datasource.hikari.auto-commit=false 로 설정하면 Transactional이 끝날때 CP를 반납하게 된다. (필요할때 반납해서 최적화)
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true로 설정하면 JDBC Connection이 Transactional이 끝날때 CP를 반납하게 한다.
spring.datasource.hikari.auto-commit=false spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
추가) hibernate 5.2 이상을 사용하고 있다면 Repository에 Transactional 선언 없이 CP 획득을 지연시키는 방법도 있다고 한다.
반응형'Spring Boot > JPA' 카테고리의 다른 글
QueryDsl projections 자바 Record에 적용하기 (1) 2024.04.23 JPA 주의점 (1) - OSIV false 설정 (open-in-view) (0) 2024.04.19 [JPA] 간단하게 OneToMany 데이터 API 구현하기 - @Embeddable, @Embedded, @ElementCollection 활용하기 (1) 2023.10.15 JPA 애플리케이션 데이터베이스 초기화 (0) 2023.09.17 Spring boot JPA/하이버네이트? (0) 2022.01.04