영속성 컨텍스트란?
영속성 컨텍스트(Persistence Context)는 엔티티를 영구 저장하는 환경을 의미합니다.
EntityManager.persist(entity);
위 코드를 이해하기 위해서는 영속성 컨텍스트의 개념을 알아야 합니다. EntityManager를 생성하면 PersistenceContext가 1:1로 생성됩니다. 엔티티의 생명주기는 다음과 같은 4가지 상태로 나눌 수 있습니다:
1. 비영속 (Transient)
- 영속성 컨텍스트와 전혀 관계없는 새로운 상태.
- 단순히 new 키워드를 사용하여 객체를 생성한 상태입니다.
Member member = new Member();
2. 영속 (Persistent)
- 영속성 컨텍스트에 관리되는 상태.
- em.persist(member)를 호출하면 member 객체는 영속성 컨텍스트에 저장됩니다.
em.persist(member);
3. 준영속 (Detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태.
- em.detach(member)를 호출하여 영속성 컨텍스트에서 객체를 분리할 수 있습니다.
em.detach(member);
4. 삭제 (Removed)
- 삭제된 상태.
em.remove(member);
영속성 컨텍스트의 구조
1차 캐시
영속성 컨텍스트에는 1차 캐시가 있습니다. 예를 들어, em.find(Member.class, 1L)을 호출하면 1차 캐시에서 member 엔티티를 반환합니다. 만약 1차 캐시에 엔티티가 없으면 데이터베이스를 조회하고, 조회한 데이터를 1차 캐시에 저장한 후 반환합니다.
1차 캐시 덕분에 같은 객체를 두 번 이상 조회할 때 데이터베이스 접근을 최소화할 수 있습니다.
쓰기 지연 SQL 저장소
영속성 컨텍스트에는 쓰기 지연 SQL 저장소도 있습니다. 엔티티를 수정하거나 저장할 때 실제 데이터베이스에 즉시 반영되지 않고, 쓰기 지연 SQL 저장소에 쿼리문이 저장됩니다. tx.commit() 호출 시점에 한꺼번에 데이터베이스에 반영됩니다.
em.persist(memberA);
em.persist(memberB);
tx.commit(); // 이 시점에 쿼리들이 한꺼번에 실행됨
Flush 메커니즘
tx.commit()을 호출하면 다음 단계가 수행됩니다:
- Flush: 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영합니다.
- 엔티티와 스냅샷을 비교하여 변경된 엔티티를 찾습니다.
- 변경된 엔티티에 대한 SQL 쿼리를 생성하여 쓰기 지연 SQL 저장소에 저장합니다.
- SQL 쿼리를 데이터베이스에 반영합니다.
- Flush 호출 시점: tx.commit(), JPQL 쿼리 실행, 그리고 em.flush() 호출 시 flush가 발생합니다. flush가 발생해도 1차 캐시는 유지됩니다.
em.persist(memberA);
List<Member> members = em.createQuery("SELECT m FROM Member m", Member.class).getResultList();
// JPQL 쿼리 실행 시 flush가 자동으로 발생하여 영속성 컨텍스트의 변경 내용이 데이터베이스에 반영됨
준영속 상태
준영속 상태는 영속성 컨텍스트에서 관리되던 엔티티가 더 이상 관리되지 않는 상태를 의미합니다. 복잡한 애플리케이션에서 사용되며, 캐시를 초기화하거나 엔티티를 분리할 때 사용합니다.
em.detach(entity); // 특정 엔티티 분리
em.clear(); // 1차 캐시 전체 초기화
em.close(); // 영속성 컨텍스트 종료
영속성 컨텍스트는 주기적으로 닫아주어야 메모리 누수를 방지할 수 있습니다.
'JAVA > JPA' 카테고리의 다른 글
인프런 JPA 6화 다양한 연관관계 매핑 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |
---|---|
인프런 JPA 5화 연관관계 매핑 기초 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |
인프런 JPA 4화 필드 컬럼 "김영한 강사" -PlusUltraCode- (1) | 2024.07.19 |
인프런 JPA 2화 생성,삭제,수정 "김영한 강사" -PlusUltraCode- (0) | 2024.07.19 |
인프런 김영한의 JPA 1화 (0) | 2024.07.18 |