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);
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. 과정은 이렇다.
- DB 에서 값을 읽어왔을때 1차 캐시에 객체를 저장하면서 최초의 상태를 SnapShot 으로 저장해놓는다.
- flush() 명령이 들어오면, 현재 상태와 snapshot 을 모두 비교한다.
- 변경된 내용이 있으면 쓰기지연 저장소에 UPDATE 문을 작성해서 넣는다.
- 자동적으로 UPDATE 문이 실행된다.
3. find() 명령으로 만든 객체를 set~ 로 수정만 해주면 트랜잭션이 커밋될 시점에 DB UPDATE 가 진행된다는 것이다.
'JPA' 카테고리의 다른 글
JPQL - Select (0) | 2021.04.23 |
---|---|
JPQL (0) | 2021.04.22 |
Entity Manager, 영속성 컨텍스트 (0) | 2021.04.13 |