--- kind: REFERENCE slug: claim-with-a-conditional-update-not-a-read title: 조건부 update로 행을 claim하고 읽은 값으로 판단하지 않는다 topic: fileserver-state-and-fencing project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: reference:claim-with-a-conditional-update-not-a-read verifiedOn: # 이 기록은 이번 회차에 실행 확인을 하지 않았다 --- # 조건부 update로 행을 claim하고 읽은 값으로 판단하지 않는다 ## 목적 읽기와 행동 사이에 상태가 바뀌어, 이미 유효하지 않은 판단으로 되돌릴 수 없는 작업을 수행하는 것을 막는다. ## 규칙 1. 읽고 나서 판단하지 않는다 조건을 갱신문의 where 절에 넣고 갱신 건수로 판단한다. 2. 되돌릴 수 없는 작업 앞에서는 특히 그렇다 물리 삭제나 외부 호출은 되돌릴 수 없다. 그 앞의 판단은 원자적이어야 한다. 3. 양쪽이 같은 사실을 본다 한쪽은 리스의 부재를 보고 다른 쪽은 만료만 보면, 둘 다 자기 기준으로 옳으면서 서로 어긋난다. 4. 상태를 명시적으로 만든다 끝났다는 사실이 값으로 없으면 각 참여자가 그것을 추론하고, 추론의 근거가 서로 다르다. 5. 청구하지 못하면 미룬다 갱신 건수가 0 이면 다른 참여자가 그 행을 들고 있다는 뜻이다. 강제하지 않고 다음 주기로 넘긴다. ## 적용 조건 여러 참여자가 같은 자원을 놓고 경합하는 정리 작업과 배치 물리 삭제나 외부 호출이 뒤따르는 판정 ## 예외 읽기와 행동이 같은 트랜잭션 안에서 행 잠금과 함께 일어나면 조건부 갱신 없이도 안전하다. 그 잠금이 실제로 걸리는지 확인해야 한다. ## 예시 정리가 쓰기 리스를 읽어 없음을 확인하고 스테이징 바이트를 지웠다. 읽기와 삭제 사이에 쓰기 작업자가 그 리스를 얻었고, 지워진 것은 업로드가 이어 쓰고 있던 객체였다. 수정 후 정리는 조건부 갱신으로 청구하고, 리스가 실제로 걸려 있으면 아무것도 청구하지 않고 미룬다. ## 관계 - **cleanup이 읽은 lease와 삭제 사이에 writer가 그 lease를 얻을 수 있었다** 이 규칙을 만든 사례다. - **CAS 튜플을 where 절에 전부 반복하고 update count를 답으로 쓴다** 같은 규칙의 상태 기계 판이다. - **시간은 DB에서, 그리고 행을 잠근 다음에 읽는다** 같은 계열의 짝 규칙이다.