가격이 안 맞는다는 문의가 왔다.
우리 DB 32,900
저쪽 화면 26,800
할인을 지우고 가격을 올렸는데 반영이 안 된 것으로 보였다. 전송 이력을 SELECT 해 보니 update_success 였다.
SELECT status, completed_at FROM distribution_product_jobs WHERE ...;
Table of contents
Open Table of contents
성공한 작업과 안 맞는 가격
성공했는데 값이 다르다는 것이 처음에는 모순으로 보였고 성공이면 저쪽에 우리 값이 들어가 있어야 할 것 같았다.
그런데 그 성공이 무엇을 뜻하는지를 따져 보니 모순이 아니라 두 문장이 함께 참일 수 있는 구조였다.
전송 성공이 뜻하는 것
update_success 는 그때 그 값을 보냈고 저쪽이 받았다는 뜻이지 지금 MySQL 값과 같다는 뜻이 아니다.
보낸 값이 26,800이었으면
↓
26,800으로 성공
↓
지금 DB는 32,900
보낸 뒤에 우리 값이 바뀌었으므로 저쪽에는 26,800 이 남았고 성공이면서 불일치인 상태가 성립한다.
두 컬럼 비교로 끝난다
이 진단을 매번 job 이력을 뒤져서 하고 있었는데 ALTER TABLE 로 컬럼을 하나 더해 마지막으로 보낸 값을 거기 저장하게 바꿨다. 그러면 현재 값과 그 컬럼을 한 SELECT 에 나란히 놓는 것으로 진단이 끝난다.
두 값이 같은데 저쪽이 다르면 저쪽 문제이고 두 값이 다르면 우리가 아직 안 보낸 것이다. 경계를 넘어가는 값은 무엇을 보냈는지를 남겨 둬야 이 구분이 가능했다.
왜 이전 값이 나갔나
왜 이전 값이 나갔는지를 보니 값을 UPDATE 하는 처리와 전송하는 처리의 순서가 어긋난 경우가 있었다. 전송 대상이 먼저 SELECT 되고 그 뒤에 값이 바뀌면 옛 값이 그대로 나간다.
다만 항상 그런 것은 아니었고 두 처리가 잡히는 시점에 따라 갈렸다. 그래서 재현하려고 하면 될 때도 있고 안 될 때도 있어서 다른 원인처럼 보였다.
재현 안 되는 순서 문제
어느 쪽인지 확정하려면 updated_at 과 전송 시각을 나란히 놓고 봐야 했다. 어느 것이 먼저 잡혔는지가 그 건의 결과를 정하기 때문이다.
시각을 보고 나서야 재현이 안 되던 것이 순서 문제라는 것이 확정됐다. 상태값이 무엇인지와 값이 같은지는 서로 다른 질문이라 상태값만 보고는 답이 안 나온다.
정리
- 전송 성공은 그때 그 값을 보냈다는 뜻이다
- 성공이면서 불일치인 상태가 성립한다
- 마지막으로 보낸 값을 컬럼에 저장해 두면 대조가 가능해진다
- 진단이 두 컬럼 비교로 끝난다
- 두 값이 같은데 저쪽이 다르면 저쪽 문제다
- 순서 문제는 시점에 따라 갈려 재현이 안 되는 것처럼 보인다
- 확정하려면
updated_at과 전송 시각을 나란히 본다 - 상태값과 값 비교는 다른 질문이다