seunGit / TIL-TodayILearned

🔥 Today I Learned
https://github.com/seunGit/TIL-TodayILearned/issues
1 stars 0 forks source link

JPA 영속성 컨텍스트 #33

Open seunGit opened 1 year ago

seunGit commented 1 year ago

JPA 영속성 컨텍스트

image

엔티티의 생명주기

Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

//객체를 저장한 상태(영속), 실제 DB에 저장 되는 것은 아님
em.persist(member);
//회원 엔티티를 영속성 컨텍스트에서 분리, (준영속 상태)
em.detach(member);

//객체를 삭제한 상태(삭제)
em.remove(member);

1차 캐시

영속성 컨텍스트에는 1차 캐시를 가지고 있다. ( 한 트랜잭션 안에서만 유효함 )

Member member = new Member();
member.setId("member1");
member.setUserName("회원1");

//1차 캐시에 저장됨
em.persist(member);

//1차 캐시에서 조회 
Member findMember = em.find(Member.class, member1); //(1차캐시에 있는 경우 캐시에서 가져옴)
Member findMember = em.find(Member.class, member2); //(1차캐시에 없는 경우 DB에서 가져오고 1차캐시에 저장 )

image

트랜잭션을 지원하는 쓰기 지연

transaction.begin();

em.persist(memberA); //1차캐시 및 쓰기 지연 SQL 저장소에 Insert쿼리가 저장 됨
em.persist(memberB); //1차캐시 및 쓰기 지연 SQL 저장소에 Insert쿼리가 저장 됨

transaction.commit(); //트랜잭션 커밋 시점에 Insert쿼리 전달

//
//하이버네이트의 옵션을 통해 한번에 쿼리를 보내고 커밋 함 일종의 버퍼링 기능
//hibernate.jdbc.batch_size

image

엔티티 수정 ( 변경 감지 )

tx.begin();

Member member = em.find(Member.class, 150L);
member.setName("ZZZZ"); //데이터 변경시 업데이트 처리 됨

//em.persist(member) 반영 할 필요 없음

tx.commit();

image

엔티티 수정 및 감지 순서

  1. Commit시점에 내부적으로 Flush가 일어난다.
  2. 1차 캐시 안에는 Id, Entity, 스냅샷을 가지고 있다. 스냅샷이란 최초로 영속성 컨텍스트에 들어온 상태
  3. 커밋되는 시점에, 엔티티와 스냅샷을 비교한다. 멤버 A객체가 변화 된것을 확인하면
  4. 쓰기 지연 SQL 저장소에 업데이트 쿼리를 만들어 놓는다.
  5. 쿼리를 DB에 반영하고 커밋처리한다.