UPDATE user_token ut SET ( ut.token, ut.last_login_dt ) = ( SELECT CASE WHEN last_login_dt < SYSDATE - 1 THEN token ELSE :new_token END token, CASE WHEN last_login_dt < SYSDATE - 1 THEN last_login_dt ELSE SYSDATE END last_login_dt FROM user_token WHERE AND user_id = :user_id ) WHERE user_id = :user_id
user_token 테이블에 user_id와 token은 각각 pk, uk이고,
대략 이런 쿼리가 있을때,
동일한 user_id로 같은 시점에 요청이 들어올 경우
로우락이 걸리고, token과 last_login_dt가 업데이트 될텐데요.
이후 대기중인 update 쿼리가 실행되면 token과 last_login_dt가 수정될까요?
서브쿼리의 실행시점이 락이 걸린이후에 실행되느냐,
아니면 락이 걸리기 전에 실행되어 캐싱되느냐 차이일것 같은데..
둘다 아닐수도 있겠지만, 어떻게 되는지 궁금합니다.
궁금한건 쿼리 최적화가 아니라 실행순서라서 궁금이 풀리진 않네요.^^;;
제시해주신 쿼리에서도 궁금한게 있는데요,
해당 쿼리가 동일한 user_id로 동시에 여러건 요청할 경우
로우락이 걸리고, 업데이트가 되고, 이후 대기중인 동일한 쿼리들이 실행 될텐데요,
첫 쿼리에서 last_login_dt가 업데이트 되었기 때문에 나머지 쿼리는 업데이트가 안되는게 맞나요?
락을 걸땐 where 조건 보고 체크하겠지만, 이후 업데이트할땐 where조건을 체크하는 궁금하네요.
꼭 이런 매커니즘이 아니더라도, 어떻게 되는지 궁금합니다.
처음 질문하게된 쿼리가 나오게 된게 저런 의문 때문이였거든요.
2번세션에서 락이 걸려 대기하다가
락이 풀리면 엡데이트가 재수행 됩니다.
대상 추출할 때는 읽기 일관성 모드로 읽고,
최종 업데이트 할 때는 현재 모드로 수행합니다.
즉, 대상 추출 시점과 갱신시점 사이에 뭔가가 발생했다면?
결과가 달라질 수 있습니다.
1. S1 : UPDATE SET b = 1 WHERE b = 0; > 정상
2. S2 : UPDATE SET b = 2 WHERE b = 0; > 대기(읽기 일관성 모드로 읽어 1건 나옴)
3. S1 : COMMIT; > 정상
4. S2 : 0 ROW UPDATED (현재 모드로 재 수행되어 0 건 나옴)
5. 최종 : b = 1