Spring Data JPA - JPA Hint & Lock

2022. 7. 31. 19:47·공부/JPA
반응형

출처 : 인프런 실전! 스프링 데이터 JPA

Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다.

 

JPA Hint & Lock

JPA Hint

JPA 쿼리 힌트(SQL 힌드가 아니라 JPA 구현체(하이버네이트)에게 제공하는 힌트이다.)

 

쿼리 힌트 사용

  • MemberRepositoryTest.class
@Test
public void queryHint() {
    Member member1 = memberRepository.save(new Member("member1", 10));
    em.flush();
    em.clear();

    //Member findMember = memberRepository.findById(member1.getId()).get(); 
    // 실무에서 get으로 바로 꺼내 쓰면 안된다.
    Member findMember = memberRepository.findReadOnlyByUsername("member1");
    findMember.setUsername("member2");

    em.flush(); // 변경 감지 동작, update 쿼리 나감
}

JPA에는 변경 감지라는 기능이 있다. 그래서 find로 가져온 객체와 원본 객체를 비교해서 flush 하는 시점에 둘이 서로 값이 다를 경우 update 쿼리가 발생한다. 이런 기능이 편리하고 장점도 있지만 단점도 존재하긴 한다. 영속성 컨텍스트에서 가지고 있는 원본 객체가 값이 수정된 걸 어떻게 알까? 바로 find() 같이 객체를 가져오면 스냅샷을 따로 찍어놓는다. flush() 할 때 스냅샷과 원본이 다를 경우 update 쿼리를 날리는 것이다. 만약 단순히 조회한 다음에 화면에 뿌리는 기능이라면 위의 과정이 너무 쓸데없이 느껴진다. 왜냐면 조회 후 바로 뿌리는데 객체를 비교할 스냅샷을 굳이 만드는 과정조차 비용이기 때문이다. 

그래서 하이버네이트에서는 단순히 조회만을 위한 기능을 제공한다. JPA에서는 그런 기능을 따로 제공하진 않고 힌트를 이용할 수 있도록 문을 열어두었다.

  • MemberRepository.interface
@QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true"))
Member findReadOnlyByUsername(String username);
@Test
public void queryHint() {
    Member member1 = memberRepository.save(new Member("member1", 10));
    em.flush();
    em.clear();

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

    em.flush();// 변경 감지 동작 안 함, update 쿼리 안나감
}

위와 같이 코드를 수정하면 find()해서 가져온 객체를 아무리 수정해도 update가 나가지 않는다. readOnly의 기능이 true면 내부 최적화를 알아서 해서 스냅샷을 따로 만들지 않는다. 그래서 수정이 일어나도 아무런 반응을 하지 않는다.

 

! readOnly로 얻을 수 있는 장점이 분명히 있지만 무분별하게 사용하면 안 된다. 전체 애플리케이션에서 조회 성능보다 더 복잡한 기능을 튜닝하는 것이 더 중요하다. 성능 테스트 후에 조회 성능에 문제가 있으면 적용하는 거지 미리 적용하거나 하는 건 비추

 

 

Lock

  • MemberRepository.interface
@Lock(LockModeType.PESSIMISTIC_WRITE)
List<Member> findLockByUsername(String username);
  • MemberRepositoryTest.class
@Test
public void lock() {
    //given
    Member member1 = memberRepository.save(new Member("member1", 10));
    em.flush();
    em.clear();

    //when
    List<Member> result = memberRepository.findLockByUsername("member1");
}
    select
        member0_.member_id as member_i1_0_,
        member0_.age as age2_0_,
        member0_.team_id as team_id4_0_,
        member0_.username as username3_0_ 
    from
        member member0_ 
    where
        member0_.username=? for update

Lock은 JPA에서 제공하는 기능이다. Lock은 내용이 어렵고 깊이 들어가야하니 김영한 님이 집필하신 JPA 책을 보고 공부하도록..! 여기서는 그냥 이런 게 있다 정도만 알면 된다.

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • Spring Data JPA - Auditing
  • Spring Data JPA - 사용자 정의 리포지토리 구현
  • Spring Data JPA - @EntityGraph
  • Spring Data JPA - 벌크성 수정 쿼리
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프로그래머스
    MSA
    전자정부프레임워크
    넥사크로
    운영체제
    방통대
    인프런
    IT
    토비의스프링부트
    oracle
    스프링부트
    프론트엔드
    RESTful
    알고리즘
    코딩테스트
    자바스크립트
    react
    SpringBoot를 이용한 RESTful Web Service 개발
    QueryDSL
    개발자
    springboot
    백준
    기출문제
    Java
    토이프로젝트
    Spring
    JPA
    egov
    에러해결
    SQL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
Spring Data JPA - JPA Hint & Lock
상단으로

티스토리툴바