Server/Spring JPA 24

Connection Pool Deadlock 해결하기! (feat. REQUIRES_NEW)

HTML 삽입 미리보기할 수 없는 소스 해당 포스팅은 서비스를 오픈하면서 겪었던 이슈와 해결에 대해 공유한다. 아래 코드 및 내용은 예시를 위해 만든 프로젝트이다! 송금 서비스 송금 서비스에서 은행 API를 호출해서 송금을 한다고 가정해보자. 아래는 예시를 위한 코드이다. @Service @RequiredArgsConstructor public class TransferService { private final TransferRepository transferRepository; private final BankingRequestRepository bankingRequestRepository; private final BankingApiAdaptor bankingApiAdaptor; @Transactio..

Server/Spring JPA 2024.03.30

Hibernate ORM 공식문서 읽어보기!

Spring JPA 기반에서 개발하다보면 아래 라이브러리를 사용하게 된다. Jakarta Persistence API Hibernate ORM Spring Data JPA Jakrta Persistence API는 명세에 해당한다. 실제 구현하는 기술은 Hibernate ORM에 있다. 해당 포스팅에서는 Hibernate ORM에 대해 공식문서를 읽고 학습 테스트를 진행하면서 알아두면 좋을 내용에 대해 소개한다. Hibernate ORM Hibernate ORM에서 소개하는 목표는 아래와 같다. Hibernate’s design goal is to relieve the developer from 95% of common data persistence-related programming tasks by e..

Server/Spring JPA 2023.12.19

QueryDsl에서 Index Hint 사용하기!

MySQL 5.7을 사용하는 프로젝트의 QueryDSL 동적 쿼리에서 특정 경우에 인덱스를 안타는 문제가 발생했다. 운영 중인 서비스에서 커버링인덱스를 탈 수 있는 상황에서는 인덱스를 선택했지만, 인덱스에 없는 컬럼 정렬 등에서 PK를 타서 쿼리가 밀리는 현상이 자주 생겼다. 그래서 Index Hint를 QueryDsl에서 사용할 수 있도록 조치가 필요했다. 아래는 해당 처리를 위해 길을 떠나면서 얻게된 방법들이다. 1. JPASQLQuery querydsl-jpa는 JPASQLQuery라는 것을 제공한다. 아래는 해당 클래스의 설명이다. JPASQLQuery is an SQLQuery implementation that uses JPA Native SQL functionality to execute q..

Server/Spring JPA 2023.12.08

JPA - OSIV 제대로 이해하기!

OSIV(Open Session In View) OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 개방하는 기능이다. 이를 사용하면 트랜잭션이 종료되어도 영속성 컨텍스트가 관리될 수 있다. 여기까지는 사실 다 아는 내용이고 OSIV의 동작 원리에 대해 알아보자. OpenInView Spring 환경에서 보통 아래의 property로 OSIV 설정에 접근한다. spring.jpa.open-in-view 아래는 JpaWebConfiguration 클래스의 애노테이션이다. open-in-view 속성에 따라 해당 Configuration이 등록된다는 것을 알 수 있다. 이를 통해 알 수 있는 놀라운 사실은 'Spring JPA도 웹과 연관이 있다.'는 것이다. JpaProperties..

Server/Spring JPA 2023.11.19

Hibernate @Where 애노테이션이 동작하지 않는 이유!

@Where 애노테이션이 동작하지 않는 이유 실무에서 Mail 일괄 수정 시 인덱스가 안타는 문제가 발생했다. 이유는 @Where(clause = "del_flag = 'N'")을 했는데, QueryDsl을 사용한 조회에서는 해당 조건을 수행하지 않아서 인덱스를 탈 수 없었다. 요즘 Hibernate 및 JPA에 대한 관심이 부쩍 늘어서 이 문제에 접근해보면 경험치를 얻을 수 있을 것 같아서 디버깅해봤다. 문제 파악 다른 코드에 대한 영향 없이 확인해야 하기 때문에 새로 프로젝트를 만들었다. 아래의 JPA Entity를 만들었다. @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Where(clause = "name = 'violet..

Server/Spring JPA 2023.11.05

Hibernate - QueryPlanCache Memory Leak 해결하기!

오늘 OOM이 터졌다는 요청이 왔다. 그래서 해당 API를 새로 배포한 후, 원인을 찾기로 했다. HeapSize 확인 첫 번째로 살펴본 부분은 HeapSize였다. java -server -Xms256m -Xmx256m 놀랍게도 HeapSize가 256m 이었다. 일단 Size가 너무 적었기 때문에 누수가 아니라, 트래픽 급증 등이 원인일 수도 있겠다고 생각을 했다. 문제가 되는 부분 해당 배치가 돌아간 시간을 확인해보니 아래 쿼리가 문제가 되었음을 확인했다. public interface CommentRepository extends JpaRepository { @Query("select m from Comment m where m.userId in (:userIds)") List findAllByU..

Server/Spring JPA 2023.06.29

HikariCP 커넥션 누수 해결기 (Session wait_timeout 적용!)

HikariCP 커넥션 누수 해결기 (Session wait_timeout 적용!) 아래의 에러가 뜨면서 커넥션 연결이 실패하는 이슈가 발생했다. the last packet successfully received from the server was 30,035 milliseconds ago. 조금더 로그를 올라가보니 이런 경고가 뜨고있었다. 아래와 같이 각 커넥션으로 연결을 시도하다가 모두 실패했다. 2023-04-18 08:01:12.345 WARN 20 --- [nio-8080-exec-9] com.zaxxer.hikari.pool.PoolBase : HikariPool-3 - Failed to validate connection com.mysql.cj.jdbc.ConnectionImpl@1d5d8..

Server/Spring JPA 2023.04.19

Spring - @Transactional(readOnly = true)을 하면 일어나는 일

왜 Service 클래스 단위에 기본적으로 @Transactional(readOnly = true) 속성을 사용할까? @Trasnactional(readOnly = true)를 사용하면 어떤 점에서 이득이 있는 지 알아보자. 예상치 못한 엔터티의 등록, 변경, 삭제 예방 @Transactional에 readOnly = true 옵션을 주면 스프링 프레임워크가 세션 플러시 모드를 MANUAL로 설정한다. 이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않게 되어서, 트랜잭션이 커밋되면서 실수로 엔터티가 등록, 수정, 삭제 되는 일을 방지한다. 성능 최적화 1. 트랜잭션을 읽기 전용으로 열면 JPA에서 제공하는 스냅샷 저장이나 변경 감지 등을 사용하지 않아서 자원(CPU, Memory)의 낭..

Server/Spring JPA 2022.11.04

Spring - Service Layer에서 Storage를 다룰 때 트랜잭션 처리하기! (커넥션, 락 과점유 피하기!)

DB 자원을 등록할 때 파일을 추가로 업로드하는 경우가 있다. 조회를 할 때 파일도 추가로 조회해야 하는 경우도 있다. Service에서 스토리지 다루기 아래 예시를 보자. @Service @RequiredArgsConstructor public class MemberService { private final MemberRepository memberRepository; private final MemberResourceService resourceService; @Transactional public Member create(CreateMemberRequest request) { Member member = new Member(request.getUsername()); memberRepository.s..

Server/Spring JPA 2022.10.25

Spring Transaction - Propagation(전파 속성)

Transaction Propagation Spring Transaction의 Propagation(전파 범위)에 대해서 알아보자. 트랜잭션 전파 범위는 트랜잭션을 시작하거나 기존 트랜잭션에 참여하는 방법과 롤백되는 범위 등에 대한 속성값이다. 종류는 다음의 7가지가 있다. REQUIRED(default) REQUIRES_NEW MANDATORY SUPPORTS NESTED NEVER REQUIRED default 속성이다. Required는 부모 트랜잭션이 존재한다면 부모 트랜잭션에 합류한다. 그렇지 않다면 새로운 트랜잭션을 만든다. 중간에 자식 / 부모에서 예외가 발생한다면 자식과 부모 모두 rollback 한다. REQUIRES_NEW 무조건 새로운 트랜잭션을 만든다. nested한 방식으로 메소드..

Server/Spring JPA 2022.10.04