JPA Hint

JPA 쿼리 힌트(SQL 힌트가 아니라 JPA 구현체에게 제공하는 힌트)

 

MemberRepository

@QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true"))

public interface MemberRepository extends JpaRepository<Member, Long> {

    // JPA Hint
    @QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true"))
    Member findReadOnlyByUsername(String username);
}

 

테스트 코드

// JPA Hint
    @Test
    public void queryHint(){
        // given
        Member member1 = new Member("member1", 10);
        memberRepository.save(member1);
        em.flush();
        em.clear();

        //when
        Member findMember = memberRepository.findReadOnlyByUsername("member1");
        findMember.setUsername("member2");

        em.flush(); // 변경 감지되어 update 쿼리가 날라감 // but ReadOnly 처리해주면 읽기로만 쓰므로 update 쿼리가 안날라감
        
    }

 

readOnly 사용으로 이루어지는 성능 최적화는 아주 적다. 

진짜 중요하고 트레픽이 많은 api에 몇개에 넣는 것

처음부터 다 튜닝하기 보다 성능테스트를 해보고 적용할지 결정.

무지성으로 넣지말자.

 

쿼리 힌트 Page 추가 예제

@QueryHints(value = { @QueryHint(name = "org.hibernate.readOnly", value = "true")}, 
		forCounting = true)
Page<Member> findByUsername(String name, Pagable pageable);

 

org.springframework.data.jpa.repository.QueryHints 어노테이션을 사용

forCounting : 반환 타입으로 Page 인터페이스를 적용하면 추가로 호출하는 페이징을 위한 count 쿼리도 쿼리 힌트 적용(기본값 true )

 

 

Lock

실시간 트레픽이 많은 서비스에선 락 걸면 안된다.

Lock - 내가 디비 쓰는동안 다른사람 접근하지마! 

select문을 제외한 다른 쿼리들은 돌아가는동안 lock을 잡게 된다.

public interface MemberRepository extends JpaRepository<Member, Long> {

    // Lock - jpa가 제공하는 Lock을 어노테이션으로 사용할 수 있다 정도만 알고 넘어가자
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    List<Member> findLockByUsername(String username);
}

 

+ Recent posts