본문 바로가기

Spring&IntelliJ

JPA 2-1강 JPA 내부 동작 방식, JPA 2-2강 영속성 컨텍스트의 이해(1), JPA 2-3강 영속성 컨텍스트의 이해(2)

https://www.youtube.com/watch?v=mj7mOMqHM68&list=PLOSNUO27qFbvzGd3yWbHISxHctPRKkctO&index=6

 

영속성 컨테이너(컨텍스트)가 곧 1차 캐시이고 이 1차 캐시(영속성 컨텍스트)에 객체를 등록해 주는 방법이 persist(customer)인 것이다. 

persis하면 1차캐시에 등록이 된 것이지 아직은 DB에 반영이 된것은 아니다. commit되는 시점에 실제로 DB에 insert되는 것이다. 

아직 DB에는 반영되지 않은 데이터를 대상으로 find메서드를 호출하면 insert쿼리가 생성되지 않고 1차 캐쉬에서 해당 객체를 find하고 반환해준다. 즉 영속성 컨테이너부터 먼저 뒤지고 그 후에 쿼리를 생성하여 날리는 것이다

persist를 두번 호출한다고하여 insert쿼리가 2번 생성되지는 않음

하나의 트랜잭션단위로 영속성 컨텍스트가 생성되는 것이다. 따라서 만약 하나의 트랜젝션내에서 persist를 해주지 않았다고 하고 find를 한다면 DB에 가서 찾기 위해 select쿼리가 만들어지는 것이다. 

 

 

https://www.youtube.com/watch?v=QBISxH_KHog&list=PLOSNUO27qFbvzGd3yWbHISxHctPRKkctO&index=7

 

persist를 하는 시점에는 1차 캐쉬(영속성 컨텍스트)에 해당 쿼리가 SQL저장소에 저장되고 commit되는 시점에 DB로 SQL저장소에 있던 쿼리가 실제로 보내지게 된다. 

flush가 이루어졌다고 바로 DB에서 그 변경된 사항을 확인할 수 있는 것은 아닙니다! 단지 DB에 반영되는 것처럼 해당 Transaction내에서 변경 사항을 확인할 수 있습니다. 다만 영속성 컨테이너와 DB의 내용을 맞춰주는(동기화) 작업이 필요할 때가 있습니다. 그때 flush를 사용하는 것입니다. JPQL쿼리실행전이나 커밋바로 이전의 상황이 그러한 동기화가 필요할 때입니다. 데이터베이스에 반영이 되었다는 것은 이미 commit을 해서 rollback을 할 수 없다는 것을 의미하기 때문에 DB에는 반영이 되지 않는 것임. 즉, 동기화라는 말뜻은 완전히 2개의 것이 똑같다는 말이 아니라 흐름을 같이 한다는 말이라고 이해하면 됨!!

동기화라는 것은 꼭 2개의 것이 같다는 것을 의미하는 것이 아니다. 다만 흐름을 같이 할뿐이다. 

정리: flush를 하면 동기화는 되지만 둘(영속성 컨테이너와 DB)의 상태가 완전히 같은 것은 아니다. 즉, 동기화란 완전히 같음을 의미하는 것이 아닌 흐름을 같이 한다는 의미이다. 

위에서 flush가 필요한 경우로 JPQL쿼리실행전을 예로 들었는데 왜 이때 flush가 필요한건가? 아래와 같이 JPQL(createQuery, getResultList())과 관련된 함수를 사용할려고 하면 하나의 트랜잭션에서 JPQL이전에 있었던 persist는 아직 DB에 반영이 되지 않은 상황이다. 이때 flush를 하지 않고 getResultList()를 한다면 오직 DB에 있는 내용만 가지고 오겠지만 flush를 하고 getResultList()를 한다면 SQL저장소에 있는 쿼리까지 모두 적용되어 모든 객체를 가져오게 되는 것이다.

 

 

https://www.youtube.com/watch?v=vMdpdui4VkA&list=PLOSNUO27qFbvzGd3yWbHISxHctPRKkctO&index=8