영속성 컨텍스트(Persistence Context)는 JPA가 엔티티(Entity)를 관리하는 메모리 공간이다.
개발자가 엔티티를 조회하거나 저장하면 DB와 바로 통신하는 것이 아니라, 먼저 영속성 컨텍스트에서 엔티티를 관리한 후 필요할 때 DB와 동기화한다.
Application
↓
JPA(Hibernate)
↓
영속성 컨텍스트
↓
Database
영속성 컨텍스트는 조회한 엔티티를 메모리에 저장한다.
예를 들어
Product p1 = productRepository.findById(1L).get();
Product p2 = productRepository.findById(1L).get();
처음 조회할 때만 SQL이 실행된다.
SELECT * FROM product WHERE id = 1;
두 번째 조회는 영속성 컨텍스트의 1차 캐시에서 가져오기 때문에 SQL이 실행되지 않는다.
JPA는 조회한 엔티티의 변경 사항을 자동으로 감지한다.
@Transactional
public void updatePrice() {
Product product = productRepository.findById(1L).get();
product.setPrice(30000);
}
save()를 호출하지 않아도 트랜잭션이 종료될 때 JPA가 변경 내용을 감지하여 UPDATE SQL을 실행한다.
UPDATE product
SET price = 30000
WHERE id = 1;
save()를 호출했다고 해서 바로 INSERT SQL이 실행되는 것은 아니다.
productRepository.save(product);
먼저 영속성 컨텍스트에 저장한 뒤,
트랜잭션이 Commit 되는 시점에 SQL을 한꺼번에 실행한다.
save()
↓
영속성 컨텍스트 저장
↓
Commit
↓
Flush
↓
INSERT / UPDATE / DELETE 실행
Flush는 영속성 컨텍스트의 변경 내용을 데이터베이스와 동기화하는 작업이다.
Flush가 발생하면
SQL이 실행된다.
하지만 Flush는 Commit과 다르다.
| 개념 | 설명 |
|---|---|
| 영속성 컨텍스트 | 엔티티를 관리하는 메모리 공간 |
| 1차 캐시 | 같은 엔티티를 다시 조회하면 DB 대신 메모리에서 반환 |
| Dirty Checking | 엔티티 변경을 감지하여 UPDATE SQL을 자동 실행 |
| 쓰기 지연(Write Behind) | SQL을 바로 실행하지 않고 Commit 시점까지 모아둠 |
| Flush | 영속성 컨텍스트의 변경 내용을 DB와 동기화 |