Server/Spring JPA 24

코루틴에서 @Transactional을 사용하는 방법!

코루틴에서 트랜잭션을 적용하는 데 어려움을 겪는 케이스가 많다.코루틴 + JPA 환경에서 @Transactional 애노테이션이 미동작했고, 해당 부분으로 인해 알게된 내용을 공유한다.Spring I/O 2024에서 언급하는 내용도 참고했다.스프링 - 트랜잭션 관리 방식스프링에서 지원하는 트랜잭션 방식에 따라 크게 2가지로 방식이 있다.선언적 트랜잭션프로그래밍적 트랜잭션선언적 트랜잭션(Declarative Transaction)이란 @Transactional과 같은 애노테이션을 기반으로 트랜잭션을 처리하는 방식을 말한다.프로그래밍적 트랜잭션은(Programmatic Transaction)은 실제 로직에서 트랜잭션을 수행하는 방식을 말한다.선언적 트랜잭션 vs 프로그래밍 트랜잭션공식문서를 보면 아래와 같이..

Server/Spring JPA 2024.09.29

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

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

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

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