반응형
flush()는 영속성 컨텍스트의 변경 사항(INSERT, UPDATE, DELETE 등)을 즉시 데이터베이스에 반영하는 동작을 의미한다.
즉, 쓰기 지연 SQL 저장소(Batch SQL Storage)에 쌓인 SQL을 강제로 실행하여 DB에 반영하는 기능이다.
1. JPA의 flush()란?
1) 변경 사항을 즉시 DB에 반영
- flush()를 호출하면 영속성 컨텍스트 내에서 변경된 엔티티의 상태가 즉시 데이터베이스에 반영된다.
- 하지만 영속성 컨텍스트를 비우지는 않는다.
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Member member = new Member();
member.setName("John");
em.persist(member); // 영속 상태 (INSERT SQL이 아직 실행되지 않음)
em.flush(); // 강제로 DB에 반영 (INSERT 실행)
em.getTransaction().commit();
2) 트랜잭션을 커밋하지 않아도 SQL 실행
- 일반적으로 flush()는 commit()과 함께 실행되지만, 명시적으로 호출하면 commit() 없이도 SQL이 실행된다.
- 하지만 트랜잭션을 롤백하면 반영된 변경 사항이 무효화된다
3) 영속성 컨텍스트는 유지됨
- flush()는 SQL만 실행하고, 영속성 컨텍스트는 그대로 유지된다.
- 즉, 엔티티는 여전히 **영속 상태(Managed)**다.
em.persist(member); // INSERT SQL은 아직 실행되지 않음
em.flush(); // INSERT SQL 실행됨
em.clear(); // 영속성 컨텍스트 초기화
2. JPA의 자동 Flush 시점
JPA는 특정 시점에서 flush()를 자동으로 호출된다.
(1) 트랜잭션 커밋 시 (commit())
- EntityManager.commit()을 호출하면 자동으로 flush()가 실행된다.
em.persist(member); // INSERT SQL 대기 상태
em.getTransaction().commit(); // flush() 실행 후, 트랜잭션 커밋
(2) JPQL 실행 전
- JPQL(Java Persistence Query Language) 실행 시 자동으로 flush()가 호출됨.
- 영속성 컨텍스트에서 최신 데이터를 반영해야 하므로, SQL 실행 전에 변경 내용을 먼저 DB에 반영.
Member member = new Member();
member.setName("JPA User");
em.persist(member); // INSERT SQL 대기 상태
List<Member> members = em.createQuery("SELECT m FROM Member m", Member.class).getResultList();
// JPQL 실행 전에 flush()가 자동 호출 → INSERT SQL 실행됨
(3) flush()를 수동 호출한 경우
- em.flush()를 직접 호출하면 즉시 데이터베이스에 반영됨.
3. flush()와 clear() 차이
메서드 | 동작 |
flush() | 변경 사항을 즉시 DB에 반영하지만, 영속성 컨텍스트는 유지 |
clear() | 영속성 컨텍스트를 초기화(모든 엔티티를 준영속 상태로 만듦) |
em.flush(); // 변경 사항을 DB에 반영하지만, 영속성 컨텍스트는 유지됨
em.clear(); // 영속성 컨텍스트 초기화 → 기존 엔티티는 준영속 상태가 됨
4. flush() 모드 설정
JPA에서는 flush()가 동작하는 방식을 설정할 수 있다.
em.setFlushMode(FlushModeType.AUTO); // 기본값
(1) FlushModeType.AUTO (기본값)
- JPQL 실행 전, 트랜잭션 커밋 시 자동으로 flush 실행
- 일반적인 경우 사용
em.setFlushMode(FlushModeType.AUTO);
(2) FlushModeType.COMMIT
- 트랜잭션이 커밋될 때만 flush() 실행
- JPQL 실행 시 flush를 하지 않으므로 성능 최적화 가능
em.setFlushMode(FlushModeType.COMMIT);
5. flush() 활용 예시
1) 배치 처리 시 flush() 활용
- 대량 데이터를 삽입할 때 flush()와 clear()를 함께 사용하여 메모리 최적화 가능.
for (int i = 1; i <= 1000; i++) {
Member member = new Member();
member.setName("Member " + i);
em.persist(member);
if (i % 100 == 0) {
em.flush(); // 100개 단위로 DB 반영
em.clear(); // 영속성 컨텍스트 초기화 (메모리 절약)
}
}
2) JPQL 실행 전 flush() 필요 없는 경우
- FlushModeType.COMMIT을 설정하면 JPQL 실행 시 자동 flush를 방지할 수 있음.
- DB 부하를 줄이고 성능 최적화 가능.
em.setFlushMode(FlushModeType.COMMIT);
List<Member> members = em.createQuery("SELECT m FROM Member m", Member.class).getResultList();
// flush()가 자동 실행되지 않음 → DB에 반영되지 않은 엔티티는 조회되지 않음
6. 정리
기능 | 설명 |
flush() | 영속성 컨텍스트의 변경 내용을 즉시 DB에 반영하지만, 컨텍스트는 유지 |
자동 flush 시점 | 트랜잭션 커밋 시, JPQL 실행 전 |
flush() vs clear() | flush()는 DB에 반영하지만, clear()는 영속성 컨텍스트 초기화 |
flush 모드 | AUTO(기본값) vs COMMIT(JPQL 실행 시 flush 방지) |
반응형
'Backend > JPA' 카테고리의 다른 글
JPA - 영속 상태와 준영속 상태의 차이 및 준영속 상태 만드는 방법 (0) | 2025.02.12 |
---|---|
JPA - 영속성 컨텍스트 (Persistence Context) 특징 (0) | 2025.02.11 |