작성
·
258
0
안녕하세요 영한팀장님
강의를 듣다가 갑자기 궁금한 부분이 생겼습니다.
더티체킹은 transaction이 commit 한 시점으로 부터 스냅샷과 DB를 비교하여 쿼리가 나간다라고 말씀해주셨는데
만약 @Transactional을 메소드에 사용한다면 예를들어
@Transactional
public void valueChange(Long id){
User user = repo.findUserByid(id)
user.setUsername("hello")
System.out.println("section1")
User user = repo.findUserByUsername("hello")
System.out.println("section2")
}
이라고 하면 제가 실험을 해본 결과 "section1" 이 출력되고 update 쿼리가 나가던데 말씀하신데로라면 @Transactional 이 끝나고 update 쿼리가 나가야 하지 않나요? 답변 기다리겠습니다. 감사합니다.
답변 1
3
범인은 바로 이 코드 입니다. (중년탐정 김전일 투로)
User user = repo.findUserByUsername("hello")
엔티티에서 키로 사용하고 있는 멤버변수는 Long타입의 Id 입니다. 그러나 findByUserName() 메서드는 키가 아닌 값으로 엔티티를 조회하고 있습니다.(String 타입의 name). 이 경우 조회 쿼리를 하기 전 모든 쓰기지연 저장소에 있던 값을 DB에 업데이트를 합니다. 왜 그렇게 작동하는지 비유를 들면..
회원의 키를 'A'라고 하고 fightnyy님이 '엔티티 관리자'라고 생각하고 봐주세요
사장님이 A회원의 거주지가 바뀌었다고 하시네요. 관리자는 A의 새로운 거주지 정보를 포스트잇에 받아 적습니다. 그때 그때 전산에 입력하는건 귀찮거든요. 이따가 퇴근전에 한번에 전산에 입력할겁니다. 관리자는 요령이 많은 사람이거든요.
그런데, 잠시 후에 사장님이 A의 거주지 정보를 가져오라고 하시네요. A라면 아까 거주지 주소가 바뀐 그 사람이네요. 일단 포스트잇에 있는걸로 전달해 드려야 겠습니다. (상황 종료)
A회원의 거주지 정보가 변경되었습니다. 관리자는 포스트잇에 이 정보를 적어놓았습니다. (상황1과 동일)
그런데, 이번엔 사장님이 "Hello"라는 사람 정보를 가져오라고 하시네요. Hello는 누구지..? 모르겠습니다. 관리자는 컴퓨터를 켜고 열심히 찾습니다. 아 Hello라는 사람 여기 있네요. 이걸 사장님에게 드리면 되겠군!
그런데 잠시후 사장님이 화를 내며 관리자를 찾아옵니다. Hello 라는 사람의 정보가 옜날거라고 하시네요. 어째서 이런일이...? 아.....! Hello라는 사람이 A 였네요. A의 거주지는 최근에 바뀌었었는데..!! 이거 큰일났네요.
같은 실수를 하지 않기 위해 관리자는 결심했습니다. 앞으로 키가 아닌 값으로 정보를 요청하면, 포스트잇에 있는걸 전부 전산에 입력한 뒤, 정보를 새로 검색해야겠다고 말입니다.
영속성으로 관리되고 있는 엔티티는 모두 더티 체킹 대상입니다. 그리고 트랜잭션이 커밋 될 때 일괄적으로 데이터베이스에 쿼리 하는게 기본 행위라고 생각하시면 되고, 가끔 flush() 를 강요하는 몇가지 행동들이 있다 라고 생각하시는게 맞는것 같습니다. 수업 하시면서 강사님이 언급해주실때가 있는데 고때 메모를 해두시면 될것같습니다. (저도 메모 안해둬서 까먹음.. 다시 봐야함..)
codesweaver님 친절한 예시 설명 감사합니다^^
더티체킹은 플러시가 호출될 때 발생합니다.
플러시는 다음의 경우에 발생합니다.
1. JPQL이 실행될 때
2. 트랜잭션이 커밋 될 때
감사합니다.
오 이해가 상당히 잘되었습니다.
그렇다면 더티체킹은 언제 발생한다! 라고 일반화 할 수 있을까요?
예를들면
1. asdasd 인 경우에
2. sididj 인 경우에
....
이런식으로도 설명해주시면 정말 감사하겠습니다!!