이전 포스팅 중 Cascade와 트랜잭션에 관해서 다룬 적이 있다.
이 둘을 포함하여 JPA를 공부하면서, 영속성 컨텍스트에 대한 개념이 많이 부족하다는 것을 느꼈다.
어렴풋이는 알고 있지만, JPA를 수월하게 다루기 위해서는 이 영속성 컨텍스트에 대한 개념은 확실하게 이해를 해야 한다고 느껴졌기에, 이번에는 이를 주제로 공부하고 기록하려고 한다.
JPA 에서 EntityManager 가 영속성 컨텍스트를 관리JPA 는 DB 와 직접적으로 상호작용하지 않고, 영속성 컨텍스트를 통해 엔티티의 상태를 관리1) 비영속 상태
2) 준영속 상태
3) 영속 상태
JPA 가 Dirty Checking을 구현하기 위한 핵심 메커니즘1) 엔티티가 영속화되면 초기 상태 저장
EntityManager 의 persist() 나 DB 를 통해 값을 직접적으로 가져오면, 해당 엔티티는 영속화되며 스냅샷으로 저장됨2) 트랜잭션 내에서 엔티티의 상태 변화 추적
EntityManager 의 메서드 직접 호출flush() -> 호출 시점에서 영속성 컨텍스트의 변경 내용을 스냅샷으로 변경refresh() -> 호출 시점에서 DB 의 값으로 스냅샷 변경 (일종의 rollback)merge() -> 준영속 상태에서 다시 영속화를 진행하면서 스냅샷 변경Dirty Checking 을 통해, 스냅샷과 현재의 엔티티 상태가 다르면 UPDATE 쿼리 자동 생성3) 트랜잭션 커밋 시
UPDATE 쿼리를 통해 DB 에 자동 반영1) 1차 캐시
DB 를 통하지 않고 이 1차 캐시에서 실행2) 쓰기 지연
DB 에 바로 반영되는 것은 아님DB 와 작업할 수 있음SQL 쿼리를 하나의 Batch 로 처리하여 성능 향상 가능3) Dirty Checking
DB 에 UPDATE4) 동일성 보장
@Transactional(propagation = ?) 으로 전파 방식 결정@Transactional
public void do() {}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void do() {}
@Transactional(propagation = Propagation.NESTED)
public void do() {}
@Transactional(propagation = Propagation.SUPPROTS)
public void do() {}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void do() {}
@Transactional(propagation = Propagation.MANDATORY)
public void do() {}
@Transactional(propagation = Propagation.NEVER)
public void do() {}
‼️ 영속성 컨텍스트의 트랜잭션 전파를 잘 사용하면, 다중 트랜잭션이 동시에 존재하거나 상호작용할 때 성능의 향상을 기대할 수 있음
참고) OpenAI. (2024).ChatGPT(4o)[Large language model].https://chatgpt.com/