작성
·
142
0
안녕하세요. 22분경, 변경감지 관련해서 질문드립니다.
순서도를 보면 flush가 두번 있어서 이 부분이 이해가 되지않아서 질문드립니다. 비슷한 다른 질문들을 찾아봤지만 이해가 되지않아서 추가적으로 질문드립니다.
1. 전체적으로아래와 같이 이해하면될까요?
JPA는 트랜잭션을 커밋할때 flush()가 호출된다.
영속성컨텍스트의 엔티티와 스냅샷을 비교한다.
UPDATE SQL을 생성해서 쓰기지연SQL저장소에 SQL쿼리를 저장한다.
쓰기지연SQL저장소에있는 쿼리를 flush를 통해 쿼리를 데이터베이스에 전송한다.
트랜잭션이 커밋된다
2.또, 추가적으로 위와 같이 이해하게 되면, 트랜잭션을 커밋할때 flush를 두번 호출하는것일까요? 두 flush가 어떤 차이인지 궁금해서 질문드립니다.
3.4번에 있는 flush는 쓰기지연SQL저장소에 UPDATE쿼리가 있어서 flush하는것으로 보면 될거같은데, 첫번째 flush는 왜 flush를 해주는것인지 이해가 되지않아 질문드립니다..
답변 7
1
y2gcoder님, 상세한 답변 정말 감사드립니다.
마지막으로 추가적으로 하나만 더 질문드리겠습니다ㅠㅠ
이 부분이 늘 헷갈렸어서 고민이어서 확실히 짚고 넘어가고싶어서요..
이전 답변에서 조금 수정해서, 아래와 같이 정리해보았는데 이렇게 이해하고 넘어가도 괜찮을까요? 그리고 아래 5번의 과정에서, 최종적으로 트랜잭션을 커밋하는 주체는 엔티티 트랜잭션이 맞을까요?
1. JPA는 트랜잭션을 커밋할때 변경된 엔티티 유무와 상관없이 항상 내부적으로 엔티티매니저의 flush()가 호출된다.
2. 영속성컨텍스트의 엔티티와 스냅샷을 비교한다.
3. UPDATE SQL을 생성해서 쓰기지연SQL저장소에 SQL쿼리를 저장한다.
4. 쓰기지연SQL저장소에있는 쿼리를 데이터베이스에 전송(=flush)한다.
5. 쓰기지연SQL저장소에있는 쿼리를 데이터베이스에 전송하고나서, 엔티티트랜잭션에 의해 트랜잭션이 커밋된다.
트랜잭션을 커밋하면 flush()가 호출되고, flush()가 호출되면 위의 2~4번의 과정이 내부적으로 진행된다.
이 과정속에서 쓰기지연SQL저장소에있는 쿼리를 데이터베이스에 전송(=flush)한다.
그리고 flush()와 flush의 차이점은 이름은 둘다 flush로 동일하지만, flush()는 엔티티매니저의 메서드 이름이고, flush는 flush()를 호출할때 내부적으로 진행되는 영속성 컨텍스트 내의 동작 중 쓰기 지연 저장소에 있는 쿼리를 모아 DB로 전송하는 동작 이름이다.
flush()를 호출하는것은 영속성 컨텍스트(영속성컨텍스트의 변경내용)와 데이터베이스를 동기화 하는작업이고, 이것은 2~4번의 과정을 말한다.
flush() = 2~4번의 작업,
flush = 4번 작업
1
답변 정말 감사합니다. 말씀해 주신거를 바탕으로 전체적으로 아래와 같이 이해하면될까요?
JPA는 트랜잭션을 커밋할때 엔티티매니저의 flush()가 호출된다.
영속성컨텍스트의 엔티티와 스냅샷을 비교한다.
UPDATE SQL을 생성해서 쓰기지연SQL저장소에 SQL쿼리를 저장한다.
쓰기지연SQL저장소에있는 쿼리를 flush를 통해 쿼리를 데이터베이스에 전송한다.
트랜잭션이 커밋된다
트랜잭션을 커밋하면 flush()가 호출되고, flush()가 호출되면 위의 2~5번의 과정이 내부적으로 진행된다. 이 과정속에서 쓰기지연SQL저장소에있는 쿼리를 flush를 통해 데이터베이스에 전송한다.
그리고 flush()와 flush의 차이점은 이름은 둘다 flush로 동일하지만, flush()는 엔티티매니저의 메서드 이름이고, flush는 flush()를 호출할때 내부적으로 진행되는 영속성 컨텍스트 내의 동작 중 쓰기 지연 저장소에 있는 쿼리를 모아 DB로 전송하는 동작 이름이다.
이렇게 이해하면될까요?
1
flush는 쓰기지연SQL저장소에 UPDATE쿼리가 있어서 flush하는것으로 보면 될거같은데, 첫번째 flush()는 따로 명시적으로 호출하는 코드가 없는데, 어떤 동작에 의해 호출되는것인가요? 트랜잭션을 커밋할 때, 변경된 엔티티 유무와 상관없이 JPA는 내부적으로 flush()
를 무조건 호출 하는것일까요?
그리고 flush()와 flush는 이름은 비슷하지만 아예 개념이 다른것인가요?
첫번째 flush()는 따로 명시적으로 호출하는 코드가 없는데, 어떤 동작에 의해 호출되는것인가요? 트랜잭션을 커밋할 때, 변경된 엔티티 유무와 상관없이 JPA는 내부적으로
flush()
를 무조건 호출 하는것일까요?
=> 말씀하신 것이 맞습니다. 플러시 모드에 대해서는 강의를 계속 진행하시다 보면 플러시에 대해 학습하실 수 있으실 거라 생각합니다. 엔티티 매니저의 기본 플러시 모드는 AUTO이고 이는 트랜잭션 커밋이나 JPQL을 실행할 때 무조건 플러시하도록 설정하는 것입니다. 실제로 변경사항이 없다면 DB로 날아가는 쿼리는 0개일 수 있으나 JPA 내부적으로는 Flush 를 통하여 동기화 를 체크하는 과정은 필요하다고 생각합니다 🙂
그리고 flush()와 flush는 이름은 비슷하지만 아예 개념이 다른것인가요?
=> 해당 부분에 대해서는 앞서 답변 드렸던 것을 참고해주시면 좋을 것 같습니다. 저는 flush()라는 엔티티 매니저에 존재하는 메서드를 통해 flush라는 동기화 동작(여기서는 쓰기 지연 SQL을 DB로 전송하는 동작입니다)이 발생하므로 큰 맥락에서는 같은 개념이라고 생각합니다.
1
flush가 두번 호출되는게 아니라, 한번 flush가 호출될때 변경을 감지하고 쓰기 지연 저장소에 SQL을 모으고나서 flush를 해주는건가요? 이해가 잘 안됩니다..
0
답변감사합니다. 아 그리고 혹시 트랜잭션 커밋전에 쿼리를 생성해서 쓰기지연저장소에 저장하는것인가요? 아니면 트랜잭션 커밋 이후 내부적으로 flush()호출 시 쿼리를 생성해서 쓰기지연 저장소에 저장하는것인가요??
0
안녕하세요. 오리쉐리님, 공식 서포터즈 y2gcoder입니다.
1번의 flush()는 엔티티 매니저에 있는 메서드를 호출한 것이고, 그 이후부터의 과정은 해당 메서드를 호출했을 때 영속성 컨텍스트에서 일어난 일을 설명한 것입니다 🙂
2번의 flush는 영속성 컨텍스트 내의 동작 중 쓰기 지연 저장소에 있는 쿼리를 모아 DB로 전송하는 flush 동작이라고 이해하시면 될 것 같습니다.
예를 들어 저희가 로그인()이라는 메서드를 만든다고 해보겠습니다. 로그인()할 때 로그인이라는 인증 정보만 생성하는 경우도 있겠지만, 해당 유저에 대한 인증정보를 생성해주기 위해서는 먼저 유저 정보가 서비스의 DB에 있는지 조회하는 과정도 필요할 것입니다. 위의 과정에 빗대어 표현을 해보자면
1) 서비스 클래스의 로그인() -> 내부에 2) 유저 정보 조회, 3) 로그인
이런 식으로 말씀드릴 수 있을 것 같습니다.
감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
질문 주신 내용에 대해서는 JPA의 변경 감지 메커니즘에 관한 부분으로, 기본적인 작동 원리를 이해하는 것이 중요합니다. 먼저, 가장 기본적인 흐름을 정리해드리면 다음과 같습니다:
트랜잭션 커밋 시 flush() 호출: 트랜잭션을 커밋할 때, JPA는 내부적으로 flush()
를 호출합니다. 이 flush()
는 변경된 엔티티를 데이터베이스에 반영하기 위해 필요한 과정입니다.
엔티티와 스냅샷 비교: flush()
가 호출되면, 영속성 컨텍스트는 관리 중인 엔티티와 그 엔티티의 초기 상태(스냅샷)를 비교하여 변경 사항을 감지합니다.
쓰기 지연 SQL 저장소에 UPDATE SQL 생성: 비교를 통해 변경된 엔티티가 감지되면, 그에 대한 UPDATE SQL
이 생성되어 쓰기 지연 SQL 저장소에 저장됩니다.
DB로 쿼리 전송: 이후, 쓰기 지연 SQL 저장소에 저장된 쿼리를 데이터베이스로 전송합니다. 이 활동이 flush
를 통해 이루어집니다.
트랜잭션 커밋: 마지막으로, 데이터베이스에서 트랜잭션이 커밋됩니다.
두 번째 flush()
가 왜 여러 번 언급되는지 혼란스러워하셨는데요, 사실 시스템적으로는 하나의 flush 과정에 여러 단계가 있는 것입니다. 초기 flush()
호출은 변경을 감지하고 쓰기 지연 저장소에 SQL을 모으는 역할을 한다면, 마지막 단계의 flush는 모은 SQL을 실제로 DB로 보내는 역할을 합니다.
강의의슬라이드가 이 과정을 잘 설명하고 있는데, 이를 통해 JPA가 변경을 어떻게 처리하는지 명확해지실 것입니다.
다음의 링크는 주제와 관련된 유사한 내용을 다룬 질문과 답변입니다. 이를 참조하시면 더욱 이해가 깊어지실 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
저도 그렇게 이해하고 있습니다 🙂