DOing
[JPA] 영속성 컨텍스트2 - 영속성 컨텍스트의 이점 본문
영속성 컨텍스트의 이점
1. 1차 캐시
2. 동일성(identity) 보장
3. 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
4. 변경 감지(Dirty Checking)
5. 지연 로딩(Lazy Loading)
1. 1차 캐시에서 조회
1차 캐시에 Map이 있고 @id가 키이고 Entity가 값이다.
DB를 바로 조회하는 것이 아니고 1차 캐시에 있는지를 확인한다. 만약 1차 캐시에 있다면 1차캐시에서 조회한다.
1-2. 1차캐시에 없다면, DB조회
* 참고 : Entity Manager(영속성 컨텍스트)는 DB트랜잭션단위로 만든다.
JPA는 Entity를 조회만 하면 무조건 영속성 컨텍스트에 올린다.
2. 영속 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true
이것이 가능한 이유는 1차캐시때문이다!
조금 더 구체적으로 이야기하면 1차 캐시로 반복가능한 읽기(REPEATABLE) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공한다.
3. 엔티티를 등록할 때 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
한번에 커밋을 보내는 것을 잘 활용하면 JPA를 씀에도 불구하고 성능을 올릴 수 있다. 만약 MyBatis를 사용했다면 개발자가 직접 지연해서 모았다가 커밋직전에 넣는다?는 굉장히 어렵다. 버퍼링을 모아서 Write하는 이점을 얻을 수 있다.
4. 엔티티 수정 - Dirty checking(변경감지)
JPA 목적은 자바 컬렉션 다루듯이 다루게 하는 것이다.
List에서 꺼내서 수정하고 다시 집어 넣지 않듯 따로 DB 저장 코드를 써주지 않아도 된다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
//em.persist(member) 이런 코드가 있어야 하지 않을까?
transaction.commit(); // [트랜잭션] 커밋
데이터베이스는 트랜잭션을 commit하는 시점에 무슨일이 벌어지는가?
commit을 하면 내부적으로 flush()가 호출된다. 그때 JPA가 Entity와 스냄샷을 전부 비교한다.(내부적으로 최적화 알고리즘 짜져있다.) 비교를 해보고 memberA가 바꼈다면 update 쿼리를 쓰기지연SQL저장소에 만들어둔다. 그리고나서 이 쿼리들을 DB에 반영한다.
출처
: 인프런 강의 - 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편
'JPA' 카테고리의 다른 글
[JPA] 연속성 전이(CASCADE) (0) | 2021.07.15 |
---|---|
[JPA] Fetch - 즉시 로딩, 지연 로딩 (0) | 2021.07.14 |
[JPA] 영속성 컨텍스트3 - 플러시 (0) | 2021.07.14 |
[JPA] 영속성 컨텍스트1 - 엔티티 생명주기 (0) | 2021.07.14 |
[JPA] 프록시(Proxy) (0) | 2021.07.14 |