해결된 질문
작성
·
524
0
IDENTITY 전략을 사용하는 경우에는 PK값을 확인하려면 디비에 직접 들어가서 확인을 한다고 하셨고, JPA를 이용해 영속성 컨텍스트에서 관리할 때, persist를 호출하는 시점에 실제 쿼리를 날려준다는 것까지는 이해를 했습니다.
Q1. 이때 플러시 과정이 일어나는지 궁금합니다.
Q2. persist를 호출해서 쿼리를 날린 이후에 영속성 컨텍스트에서 관리하는 것처럼 쿼리들을 모아놓는 저장소에 저장이 되었다가 rollback을 하거나 commit이 되는 시점에서 이전에 persist로 인해서 생긴 변화는 더티 체크가 되는지, 된다면 어떻게 되는지 궁금합니다.
답변 5
1
1
안녕하세요. 홍철님
Q1. 이때 플러시 과정이 일어나는지 궁금합니다.
-> IDENTITY 전략의 경우 em.persist 즉시 해당 엔티티를 데이터베이스에 플러시 합니다. 왜냐하면 영속성 컨텍스트에 저장하려면 PK가 필수이기 때문입니다.
Q2. persist를 호출해서 쿼리를 날린 이후에 영속성 컨텍스트에서 관리하는 것처럼 쿼리들을 모아놓는 저장소에 저장이 되었다가 rollback을 하거나 commit이 되는 시점에서 이전에 persist로 인해서 생긴 변화는 더티 체크가 되는지, 된다면 어떻게 되는지 궁금합니다.
-> 네 더티 체크가 됩니다.
감사합니다^^
0
데이터베이스 트랜젝션 레벨을 READ UNCOMMITTED 으로 설정해둔 상태로 persis() 를 호출해보니 persis() 가 호출되는 시점에 바로 바로 입력되는 것을 확인할 수가 있네요 :)
제가 테스트한 경우는 H2 였구요, 사용한 SQL 은 아래와 같습니다.
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM MEMBER ;
0
희수님 답변 감사합니다.
작성해주신 답변 내용은 IDENTITY가 아닌 경우에 해당하는 내용인 것 같습니다.
@Entity 애노테이션을 달아준 클래스에서 @Id 설정을 해줄 때, @GeneratedValue(strategy = GenerationType.IDENTITY)로 설정을 해준 다음 persist()를 호출해주면 호출한 시점에서 insert 쿼리가 날아갑니다.
쿼리를 날려준 다음에 commit()을 하기 전에 잠시 프로그램을 멈춘 상태에서 확인을 해보니 디비에는 반영이 안된 상태였습니다.
그리고 그 쿼리 이후에 에러가 발생하도록 테스트를 진행해봤더니 catch문에서 해당 에러를 잡아주고 rollback을 해서 실제 디비에는 반영이 안된 것을 알았습니다.
저는 이런 테스트를 진행해본 결과 저는 persist()를 호출한 시점에 쿼리가 나가는 것을 확인했습니다.
또한 같은 코드에서 GenerationType만 SEQUENCE로 바꿔준 경우에 insert쿼리가 나가는 시점이 다른 것도 테스트를 통해서 확인했습니다.
그래서 저는 IDENTITY일 때, persist를 호출한 시점에서 내부적으로 어떤 처리가 되는지 알아보고싶었지만, 그 방법을 잘 모르겠어서 이렇게 질문을 남겼습니다.
0
제가 이해하기론 persist 호출하는 시점엔 쿼리가 나가지 않고 쓰기 지연 SQL 저장소에 축적되는 것으로 알고 있습니다.
이런 축적된 쿼리는 트랜잭션 단위가 끝나는 시점에 한번에 요청되는 것으로 이해하였습니다.
이러한 원리를 비추어 보았을 때 트랜잭션 단위에서 문제가 발생되었다면 해당 쿼리를 요청하지 않아 자연스럽게 DB 반영이 되지 않을 것이라 생각합니다.
또한, persist 된 이후 해당 엔티티는 영속성 컨텍스트로부터 관리되기 때문에 트랜잭션이 끝나는 시점의 값과 영속성 컨텍스트에 관리된 값과 비교하여 변경된 부분이 있다면 그때 update 쿼리를 요청하는 것으로 알고 있습니다.
부디 도움이 되었으면 좋겠습니다.