Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

DOing

[JPA] 영속성 컨텍스트2 - 영속성 컨텍스트의 이점 본문

JPA

[JPA] 영속성 컨텍스트2 - 영속성 컨텍스트의 이점

mangdo 2021. 7. 14. 19:56

영속성 컨텍스트의 이점

1. 1차 캐시

2. 동일성(identity) 보장

3. 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

4. 변경 감지(Dirty Checking)

5. 지연 로딩(Lazy Loading)

 


 

1. 1차 캐시에서 조회

1차 캐시에 Map이 있고 @id가 키이고 Entity가 값이다.

DB를 바로 조회하는 것이 아니고 1차 캐시에 있는지를 확인한다. 만약 1차 캐시에 있다면 1차캐시에서 조회한다.

 

1-2. 1차캐시에 없다면, DB조회

 

* 참고 : Entity Manager(영속성 컨텍스트)는 DB트랜잭션단위로 만든다.

 JPA는 Entity를 조회만 하면 무조건 영속성 컨텍스트에 올린다.

 

2. 영속 엔티티의 동일성 보장

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true

이것이 가능한 이유는 1차캐시때문이다!

조금 더 구체적으로 이야기하면 1차 캐시로 반복가능한 읽기(REPEATABLE) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공한다.

 

3. 엔티티를 등록할 때 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.

transaction.begin(); // [트랜잭션] 시작

em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.


//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋

쓰기 지연 
commit시에 SQL들이 한꺼번에 날라간다.

한번에 커밋을 보내는 것을 잘 활용하면 JPA를 씀에도 불구하고 성능을 올릴 수 있다. 만약 MyBatis를 사용했다면 개발자가 직접 지연해서 모았다가 커밋직전에 넣는다?는 굉장히 어렵다. 버퍼링을 모아서 Write하는 이점을 얻을 수 있다.

 

4. 엔티티 수정 - Dirty checking(변경감지)

JPA 목적은 자바 컬렉션 다루듯이 다루게 하는 것이다.

List에서 꺼내서 수정하고 다시 집어 넣지 않듯 따로 DB 저장 코드를 써주지 않아도 된다.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

//em.persist(member) 이런 코드가 있어야 하지 않을까?
transaction.commit(); // [트랜잭션] 커밋

 데이터베이스는 트랜잭션을 commit하는 시점에 무슨일이 벌어지는가? 

 commit을 하면 내부적으로 flush()가 호출된다. 그때 JPA가 Entity와 스냄샷을 전부 비교한다.(내부적으로 최적화 알고리즘 짜져있다.) 비교를 해보고 memberA가 바꼈다면 update 쿼리를 쓰기지연SQL저장소에 만들어둔다. 그리고나서 이 쿼리들을 DB에 반영한다.

 

 

출처 

: 인프런 강의 - 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편