본문 바로가기

JPA

영속성 컨텍스트를 쓰면 좋은점

1차 캐시

1. 엔티티 매니저는 영속성 컨텍스트를 가지고, 영속성 컨텍스트는 1차캐시를 가진다.

 

2. 1차 캐시는 DB 에 영속화하고 영속화한 데이터를 꺼내오는 작업 사이의 캐시이다.

 

3. 1차 캐시는 영속성 컨텍스트에 @Id 로 지정한 값을 key, 그 객체 자체를 value 로 가지게 된다.

 

4. 두 존재 사이의 존재는 어디서든 (io 의 bufferedReader 같은 버퍼) 캐시역할과 버퍼역할을 할 수 있다. JPA 의 1차캐시에서도 마찬가지다.

 

5. 엔티티메니저는 보통 트랜잭션 단위로 생성하기 때문에, 영속성 컨텍스트 안의 1차캐시도 트랜잭션 단위로 생성되고 제거된다.

 

6. 영속 엔티티 객체의 동일성을 보장한다.

System.out.println("=====");
Member member1 = em.find(Member.class, 1L);
System.out.println("=====");
Member member2 = em.find(Member.class, 1L);
System.out.println("=====");
System.out.println(member1 == member2);

select 문이 한번만 실행된다, 두번째는 1차 캐시에서 가져오는것을 알 수 있다.

true 가 나왔음을 볼 수 있다.

 

DB 의 트랜잭션에는 격리 수준이라는 것이 있는데, Repeatable Read 등급의 격리 수준을 애플리케이션단에서 제공해준다고 할 수 있다.

 

 

 

7. persist() 로 영속화한 값, DB에서 find() 로 꺼내온 값 둘 다 1차캐시에 저장해두고 쓸 수 있다. 

 

 

쓰기 지연

1. DB 에 쓰는 기능은 네트워크를 왔다갔다 해야 하기 때문에 자주 왔다갔다 하는 것은 비용적으로 비효율적이다.

 

2. JPA 의 엔티티 매니저에는 쓰기 지연 저장소가 있다. DB 에 작성하는 insert 문을 persist() 호출이 되는 시점에 날리는 것이 아니라, 쓰기 지연 저장소에 저장해뒀다가 해당 트랜잭션의 commit() 이 호출되는 시점에 한꺼번에 보낸다.

 

3. 버퍼의 역할을 한다고 할 수 있다.

 

Member first = new Member();
first.setId(3L);
first.setName("a");
Member second = new Member();
second.setId(4L);
second.setName("b");

System.out.println("--- persist(a) ---");
em.persist(first);
System.out.println("--- persist(b) ---");
em.persist(second);
            
System.out.println("--- commit ---");
transaction.commit();

 

 

 

 

 

변경 감지

1. 영속성 컨텍스트 안에 있는 객체를 수정만 해도 DB 에서의 변경이 이루어진다.

 

2. 과정은 이렇다.

  1. DB 에서 값을 읽어왔을때 1차 캐시에 객체를 저장하면서 최초의 상태를 SnapShot 으로 저장해놓는다.
  2.  flush() 명령이 들어오면, 현재 상태와 snapshot 을 모두 비교한다.
  3. 변경된 내용이 있으면 쓰기지연 저장소에 UPDATE 문을 작성해서 넣는다.
  4. 자동적으로 UPDATE 문이 실행된다.

3. find() 명령으로 만든 객체를 set~ 로 수정만 해주면 트랜잭션이 커밋될 시점에 DB UPDATE 가 진행된다는 것이다.

 

'JPA' 카테고리의 다른 글

JPQL - Select  (0) 2021.04.23
JPQL  (0) 2021.04.22
Entity Manager, 영속성 컨텍스트  (0) 2021.04.13