Skip to content
isdnetworks
Go back

건수로 갈리지 않는 것

같은 송장번호가 원본 주문과 교환 재발송 주문 두 건에 물려 있었다. 입점사가 기존 송장을 다시 입력한 것으로 보였지만 그렇게 단정하기 전에 확인할 것이 있었다.

Table of contents

Open Table of contents

증상 — 두 건에 물린 같은 송장

같은 식별자가 두 곳에 있다는 사실만으로는 어떻게 그렇게 됐는지가 나오지 않는다. 두 번 따로 입력된 것일 수도 있고 한 건을 나중에 덮어쓴 것일 수도 있다.

두 경우는 이후 처리가 달라지므로 갈라야 했다. 어느 쪽인지에 따라 안내할 내용도 바로잡을 값도 달라진다.

출고 건수의 한계

먼저 출고 처리가 몇 번 일어났는지를 COUNT(*) 로 세어 봤다. 두 번이면 각각 입력된 것이고 한 번이면 덮어쓴 것이라고 생각했다.

그런데 그 COUNT(*) 로는 두 경우가 안 갈렸다. 덮어쓰기로 처리된 경우에도 건수가 같게 나올 수 있는 구조였기 때문이다.

원인 — created_at 과 updated_at 이 갈랐다

그래서 각 행의 created_at 과 updated_at 을 나란히 놓고 봤다. 둘이 같으면 만들어진 뒤 손대지 않은 것이고 다르면 나중에 무언가 바꾼 것이다.

한 건은 두 시각이 달랐고 그 차이가 며칠이었다. 건수로 안 갈리던 것이 시각 두 개를 대조하니 갈렸다. 그렇게 읽는 근거는 updated_at 이 ON UPDATE CURRENT_TIMESTAMP 로 자동 갱신되는 컬럼이라는 점이다. MySQL 5.7 매뉴얼은 그 컬럼이 다른 컬럼 값이 현재 값에서 바뀔 때만 갱신되고 전부 같은 값으로 쓰면 그대로라고 적는다.

이력 문구와 실제 동작

확증을 위해 이력 표도 SELECT 해 봤는데 거기에는 생성이라고 찍혀 있었다. 시각 대조와 반대되는 기록이었다.

grep 으로 코드를 확인해 보니 갱신 경로에서도 그 이력을 생성으로 남기고 있었다. 이력의 문구와 실제 동작이 다를 수 있으므로 문구만 읽고 판단하면 뒤집힌다.

경과일 계산의 오염과 충돌 기록

이 구분이 필요했던 이유가 하나 더 있었는데 경과일을 created_at 기준으로 재고 있었다. 덮어쓴 건에서는 그 기준이 실제 출고 시점과 달라서 계산이 오염된다.

조사 기록을 남길 때 앞서 적힌 내용과 어긋나는 부분을 지우는 것과 남기는 것 두 가지 방법 중 남기고 충돌을 명시하는 쪽을 골랐다. 이유는 새 관측이 옛 기록을 자동으로 이기는 것이 아니라 둘 다 표본 하나라는 점이다. 대신 기록이 길어지고 읽는 사람이 어느 쪽이 맞는지 한 번 더 따져야 하는 것을 감수했다.

정리


Share this post on:

Previous Post
침묵을 고친 뒤의 폭주
Next Post
되살아나지 않는 정체 건