728x90
JPA를 사용한다는 것은 영속성 컨텍스트를 사용한다는 것이고 그럼 영속성 컨텍스트의 이점을 누릴 수 있다는 말과 같다고 생각합니다.
영속성 컨텍스트 특징
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
1. 1차캐시
1차 캐시에 들어있는 entity의 경우 DB를 거치지 않고 조회가 가능합니다.
하지만 1차 캐시에 없는 member2를 조회한다면?em.find(Member.class, "member2")
- 엔티티매니저를 통해서 entity를 조회하고 1차 캐시에 없다면
- DB를 조회해서 entity를 찾는다. 찾은 entity를 1차 캐시에 저장을 하고
- 반환합니다.
2. 동일성 보장
JPA의 영속성 컨텍스트는 동일성을 보장합니다.
Tip)
동일성: 주소값이 같은 것을 의미 == 비교
동등성: 값이 같은 것을 의미 equals()
member1 == member2
참일까? 거짓일까?
Member member1 = em.find(Member.class, "member1");
Member member2 = em.find(Member.class, "member1");
System.out.println(member1 == member2);
결과는 참입니다. entity를 조회할때 member1
이라는 동일한 Id
로 조회했기 때문에 1차 캐시에서 당연히 같은 entity가 조회될 것입니다.
3. 트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begi();
em.persist(memberA);
em.persist(memberA);
//이때까지 INSERT SQL를 데이터베이스에 보내지 않는다.
trasaction.commit(); // 이때 쓰기 지연 SQL 저장소에 있는 모든 SQL을 보낸다.
persist(member2)
를 하면 바로 DB에 저장이 되는 것이 아니라 영속성 컨텍스트의 1차 캐시에 등록이 되고 동시에 쓰기 지연 SQL 저장소에 저장할 SQL이 생되어서 저장됩니다.
transaction.commit()
커밋을 하는 시점에 쓰기지연 SQL 저장소에 있던 모든 SQL이 DB에 flush()
되고 그 다음 commit()
이 됩니다.
flush
: 쓰기 지연 SQL 저장소에 있던 SQL을 DB에 동기화하는 작업
4. 변경 감지
Member member = em.find(Member.class, "member1");
member.setName("ttttt");
- Entity가 1차캐시에 들어가는 최초 시점에 스냅샷을 찍어둔다.
flush()
를 할 시점에entity
와스냅샷
사이에 변경이 있다면UPDATE SQL
을 생성해서 쓰기 지연 SQL 저장소에 저장한다.- DB에
commit
한다.
728x90