엔티티 매니저는 트랜젝션을 커밋하기 전까지 데이터베이스에 엔티티를 저장하지 않고
내부 쿼리 저장소에 INSERT SQL을 모아둠
그리고 커밋할때 모아둔 쿼리를 데이터베이스에 보내는데 이것을 트랜잭션을 지원하는 쓰기지연(transactional write-behind)이라 한다.

이렇게 SQL저장소에 쿼리문을 저장했다가 밑의 그림처럼 flush문을 실행하면 DB에 쿼리문이 날라가서 실행된다.
flush: 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화 하는 작업인데 이때 등록, 수정, 삭제한 엔티티를 데이터베이스에 반영한다.

flush는 단순히 지연SQL저장소에 모인 쿼리를 데이터베이스에 보내는 것이고,
commit은 그것과 더불어서 commit을 하는것이다.
commit이라는 것은 "commit문"의 깃발을 꽂는다고 생각하면 된다. "이게 내가 한거야!!" 하면서 단계를 표시해두는 역할도 한다는 말임
따라서 commit() = flush + commit 인거다!!
begin()// 트랜잭션 시작
save(A);
save(B);
save(C);
commit() // 트랜잭션 커밋
이 코드를 쓰기 지연을 할때와 안할때로 나누어서 로직을 생각해보자!
1. 쓰기 지연을 하지 않을때: 개발자가 데이터를 저장하는 즉시 등록 쿼리를 데이터베이스에 보낸다. 그리고 마지막에 트랜젝션을 커밋
2. 쓰기 지연을 할때: 개발자가 데이터를 저장하면 등록쿼리를 메모리에 모아둔다. 그리고 트랜젝션을 커밋할때 모아둔 등록 쿼리를 데이터베이스에 보낸 후 커밋한다.
둘다 트랜잭션 범위 안에서 실행되므로 둘의 결과는 같다. A,B,C 모두 트랜잭션을 커밋하면 함께 저장되고 롤백하면 함께 저장되지 않는다.
등록 쿼리를 그때그때 데이터베이스에 전달해도 트랜잭션을 커밋하지 않으면 아무 소용이 없다.
이 쓰기 지연을 잘 활용하면 모아둔 등록 쿼리를 데이터베이스에 한 번에 전달해서 성능을 최적화 할 수 있다.
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경 시 트랜잭션을 시작해야 한다.
transaction.begin();
em.persist(memberA);
em.persist(memberB);
//여기까지는 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // 트랜잭션 커밋
참고자료: 김영한. [자바 ORM표준 JPA 프로그래밍],2015
계속 공부하다 보면 각 단어 들의 의미가 헷갈리는데 기본적인 정의는 이렇다
그래서 Hibernate는 JPA의 구현체인거고 Hibernate는 Session인터페이스를 이용해서 EntityManager같은 클래스의 여러 메소드를 사용가능함
참고자료: https://docs.jboss.org/hibernate/orm/5.4/javadocs/org/hibernate/Session.html
| JPA에서 Cascade Type을 지정하지 않으면? (0) | 2024.06.01 |
|---|---|
| [JPA/Hibernate] Flush란? (0) | 2024.05.30 |
| [JPA/Hibernate]엔티티 수정/ 변경감지(Dirty Checking) (0) | 2024.05.30 |
| 영속성 컨텍스트의 엔티티 조회!! (0) | 2024.05.27 |
| [JPA] 엔티티 생명 주기/영속성 컨텍스트란? (0) | 2024.05.27 |