1. 오늘 학습한 내용
1.1. JPA 영속성 컨텍스트
1.2. 영속성 컨텍스트란?
- 엔티티의 생명주기를 추적하고 변경 사항을 동기화하는 1차 캐시 저장소
- 메모리 내에서 관리되며 DB와 동기화 → Entity
- EntityManager 단위로 생성되며, 트랜잭션 범위에 종속되어 동작
- Spring Bean으로 제공되는만큼 싱글톤으로 제공됨
- 그러면 어떻게 여러 DB 작업을 처리할까?
- 프록시 객체를 이용하며, 참조를 통해 실제 객체의 메서드를 호출
1.3. Entity의 상태 변화
- 비영속 (new):
EntityManager에 의해 아직 관리되지 않는 상태 - 영속 (managed): 영속성 컨텍스트에 저장되어 JPA가 관리하는 상태
- 준영속 (detached): 영속성 컨텍스트에서 분리된 상태 (더 이상 관리되지 않음)
- 삭제 (removed): 삭제가 예정된 상태 (트랜잭션 커밋 시 삭제됨)
1.4. 영속성 컨텍스트의 역할
-
1차 캐시: 동일한 엔티티는 한 번만 DB에서 조회해 메모리에 저장
Member m1 = em.find(Member.class, 1L); // DB 조회 Member m2 = em.find(Member.class, 1L); // 1차 캐시에서 조회 System.out.println(m1 == m2); // true (동일성 보장) -
변경 감지: 엔티티 필드가 변경되면 트랜잭션 커밋 시 자동으로 UPDATE 쿼리 실행
Member member = em.find(Member.class, 1L); member.setName("newName"); // em.update(member) --> update를 해야 반영될것이야! tx.commit(); // 자동으로 UPDATE 쿼리 실행됨 -
쓰기 지연: SQL 쿼리를 모아뒀다가 트랜잭션 종료 시 일괄 실행하여 성능 최적화
em.persist(memberA); em.persist(memberB); // INSERT 쿼리는 아직 실행되지 않음 tx.commit(); // 이 시점에 INSERT 쿼리 일괄 실행 -
동일성 보장: 같은 ID를 가진 엔티티는 동일한 객체로 유지됨 (reference 비교)
1.5. flush와 commit
flush()flush()는 영속성 컨텍스트의 변경 내용을 즉시 데이터베이스에 반영하는 명령- 하지만 트랜잭션은 종료되지 않으며, 이후
commit()시 또 한 번 동기화 - 그렇기에 영속성 컨텍스트를 비우지 않음
commit()- 트랜잭션 종료 시 자동 호출되며 flush()를 호출 함
- 트랜잭션이 종료됨
2. 더 알아볼 내용 / 다음에 할 내용
- JPA의 추상화 과정과 Spring Data JPA