Persistence Context2
영속성 컨텍스트2
Last updated
영속성 컨텍스트2
Last updated
애플리케이션과 DB 사이에 논리적 무언가(영속 컨텍스트)를 만들어서 얻는 이점
1차 캐시
동일성(identity) 보장
트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
변경 감지(Dirty Checking)
지연 로딩(Lazy Loading)⭐️⭐️⭐️⭐️⭐️(후에 자세히 다룰 예정)
EM DB 트랜잭션 단위로 만들고, 트랜잭션 끝나면 EM도 종료시킨다. 고객 요청1이 들어와서 비즈니스가 끝나버리면 영속성 컨텍스트도 지운다! 1차 캐시도 날악간다! 그렇기 때문에 같은 트랜잭션 내(짧은 찰나의 순간)에서 1차 캐시에 접근할 때 이점이 있기 때문에 사실상 1차 캐시로 인한 이점은 크지 않다.
1. 1차 캐시 확인 실습
em.find()로 엔티티를 찾는데 DB SELECT 쿼리각 나가지 않았는데 값이 조회된 것을 알 수 있다! => DB가 아니라 다른 어딘가에서 데이터를 가져온다고 생각할 수 있다! 그곳이 바로 1차 캐시이다!
em.persist(entity)에서 1차 캐시에 엔티티가 저장된다! find()는 DB가 아니라 이 1차 캐시에서 데이터를 가져온다!
식별자(id)로 엔티티를 구분하기 때문에 동일한 식별자를 갖는 엔티티에 대해서 2번 조회하면 처음에만 DB에서 가져오고 2번째는 해당 식별자가 1차 캐시에 있기 때문에 DB 조회❌ SQL❌
EntityManager.find(Member.class, "id"); 1차 캐시 또는 DB에서 id(식별자)로 엔티티를 찾는다!
2. 영속 엔티티의 동일성 보장 : 같은 트랜잭션 내에서 동일한 식별자를 갖는 엔티티는 동일성이 보장된다! 1차 캐시에 있기 때문이다!
3. 쓰기 지연
쓰기 지연 SQL 저장소라는 곳에 INSERT SQL을 생성해서 차곡차곡 저장한다.
버퍼링 기능 : JDBC의 batch hibernate.jdbc.batchsize value="10" : batchsize만큼 쿼리를 한번에 모아서 커밋한다!
트랜잭션이 커밋되는 시점에 한번에 처리된다!
4. 엔티티 수정 감지(Dirty Checking의 매커니즘)
값을 변경할 때 그냥 컬렉션의 객체를 수정하듯이 setter로 값만 셋팅하면 DB도 업데이트되있다!? 어떻게 가능한 것일까?
스냅샷 : 데이터를 읽어온 최초 시점의 상태를 스냅샷이라고 한다. 최초로 영속성 컨텍스트, 1차 캐시에 들어온 시점.
그래서 최초의 데이터인 스냅샷과 현재 엔티티를 비교한다! 수정된 엔티티가 있다면 UPDATE 쿼리를 쓰기 지연 SQL 저장소에 만들어둔다! UPDATE 쿼리들을 DB에 반영하고 commit 한다! (JPA는 DB에 커밋되는 시점에 UPDATE 쿼리를 반영한다!⭐️)