JaeniWorld

[JPA] Persistence context 의 특징 본문

프로그래밍/JPA

[JPA] Persistence context 의 특징

jaeni 2021. 3. 9. 17:15
반응형

1차캐시 (First level cache)

EntityManagerpersist() 혹은 find()를 호출하면 그 entity managed상태가 되면서 Persistence context 1차캐시에 저장됨.

-      1차캐시는 Map형태로 Key@ id로 지정한 식별자이고, Value는 엔티티 인스턴스이다.

-      Entitypersistence context에 저장한 뒤, 바로 조회하면 entitypersistence context 1차캐시에 들어가 있기 때문에 SELECT 쿼리를 수행하지 않고 1차캐시에서 entity를 조회해 값을 반환한다. (DB에 가지않음)

-      조회시에도 우선 1차캐시에 해당 entity가 존재하고 있는지 확인한 후 1차캐시에 존재하지 않을 때, DB를 조회에 값을 반환한다

-      1차캐시는 글로벌 하지 않기 때문에 해당 스레드가 시작할 때부터 끝날 때까지 만 사용하고, 공유하지 않는다.

-      EntityManager의 개수만큼 생성되고 스레드가 종료되면 삭제된다.

 

2차캐시 (Second level cache)

어플리케이션 단위의 캐시로, 어플리케이션이 종료할 때까지 캐시가 유지된다.

-      2차캐시는 동시성 극대화를 위해 캐시한 객체를 직접 반환하지 않고, 복사본을 만들어 반환 (직접 반환 시, 여러곳에서 같은 객체를 동시 수정할 수 있기 때문에 문제 발생 이를 위해서 락을 거는거 보다는 객체를 복사하는 것이 효율적)

-      DB조회 시, Entity Manager1차캐시에서 먼저 조회 후, 2차 캐시에서 조회하며 2차캐시에도 존재하지 않을 경우 DB를 조회해 1,2차 캐시에 저장한다.

 

동일성 보장

매번 DB에서 가져오는 것이 아니라, 1차캐시에 영속된 Entity를 반환하기 때문에 영속된 Entity의 동일성을 보장한다. 그렇기 때문에 “==” 비교에서 true 반환한다. (데이터베이스가 아닌 애플리케이션 차원에서 제공함)

Member a = entityManager.find(Member.class, ”member1”);

Member b = entityManager.find(Member.class, ”member1”);

System.out.println(a==b); // true 반환

 

엔티티 등록 시, 쓰기 지연 (Transaction write behind)

Entity를 영속상태로 만든다음 INSERT쿼리를 수행하면 바로 DB에 추가되는 것이 아니라 Persistence context내부에 있는 쿼리 저장소에 저장해놓음. 이후, Entity Manager Transaction을 통해 commit()하면 SQL 저장소에 있던 쿼리를 DB로 보내 DB에 추가된다.

Persistence Context  1 차캐시, SQL저장소

 

변경 감지(Dirty Checking)

Persistence context가 관리하는 Entity에 한해서 (준영속, 비영속 모두 포함하지 않음) Transaction이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 데이터베이스에 자동 반영해주는 특성 때문에, 변경사항을 save 메소드를 사용하여 저장하지 않아도 DB에 자동반영해준다.

-      변경 감지 매커니즘

Transaction.commit()을 하면 flush()가 일어날 때, entity와 스냅샷을 일일이 비교 -> 변경사항이 존재한다면 UPDATE Query 생성 -> 해당 쿼리를 SQL저장소에 넣음-> UPDATE QueryDB반영 후 Commit().

-      스냅샷

엔티티가 1차 캐시에 최초로 저장될 때 그 상태를 복사해서 같이 저장해 놓은 것

-       UPDATE Query는 엔티티의 모든 필드에 대해서 업데이트가 진행되며, @DynamicUpdate 어노테이션을 엔티티 정의 시에 추가하면, 실제로 Update되는 필드에 한해서 UPDATE가 진행됨

 

삭제 (remove)

Remove 메소드를 호출하면 바로 DB에 반영되는 것이 아니라 SQL 저장소에 저장하고 있다가 Flush된 후에 Persistence Context에서 엔티티를 삭제하고 DB에서도 해당 데이터를 삭제

 

플러시 (Flush)

Persistence context의 변경내용을 DB에 반영하는 것으로 Transaction.commit()이 일어날때 동작하며, 쓰기 지연 저장소에 쌓아놨던 INSERT, UPDATE, DELETE SQLDB에 적용된다. 실제로는 Query를 보내고 나서 Commit()한다.

-      호출방법

entityManager.flush() / transaction.commit()호출 / JPQL쿼리 실행시 자동호출

플러시는 Persistence context를 비우는 것이 아니라 변경 내용을 데이터베이스와 동기화하는 역할이다.

반응형

'프로그래밍 > JPA' 카테고리의 다른 글

[JPA] 영속성 컨텍스트(Persistence Context)  (0) 2021.01.13
Comments