영속성 컨텍스트 2부
참고
엔티티 조회, 1차 캐시
//엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//엔티티를 영속
em.persist(member);
- 1차 캐시에서 조회
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//1차 캐시에 저장됨
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
- 데이터베이스에서 조회
Member findMember2 = em.find(Member.class, "member2");
영속 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true
- 1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭 션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공
엔티티 등록 트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
엔티티 수정 (Dirty Checking)
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member) 이런 코드가 있어야 하지 않을까?
transaction.commit(); // [트랜잭션] 커밋
- 왜 수정 쿼리시, persist를 호출하지 않을까?
- JPA의 dirty checking 때문이다.
- 비밀은 영속성 컨텍스트 안에 있다.
- 트랜젝션 커밋 시에, flush()가 호출되는데 그 후에, 엔티티와 스냅샷을 비교한다.
- 여기서, 스냅샷은 최초로 읽어온 시점, 그 시점을 스냅샷으로 떠온다.
- 일일이 비교 후, 바뀐 부분을 update query 생성 후, 쓰기 지연 SQL 저장소에 넣어둔다.
- DB 반영 후 Commit
엔티티 삭제
//삭제 대상 엔티티 조회
Member memberA = em.find(Member.class, “memberA");
em.remove(memberA); //엔티티 삭제
후기
영속성 컨텍스트의 하이라이트 엔티티 수정에서 발하는것 같다.
수정 부분을 보면서 persist()를 따로 호출도 안했는데 쿼리가 날라가고 반영이 되었다는게
많이 신기하였다.
Author And Source
이 문제에 관하여(영속성 컨텍스트 2부), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@roberts/영속성-컨텍스트-2부저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)