마켓별 fee_policies 의 fee 가 잘못 들어간 건이 여러 개 나왔다. MySQL 의 fee_policies 를 UPDATE 로 일괄로 고치면 끝나는 일로 보고 쿼리를 짜기 시작했다.
UPDATE fee_policies SET fee = 0.001 WHERE id IN (...);
십여 건이었다.
Table of contents
Open Table of contents
상황 — 정책 값과 일괄 수정
수정 쿼리를 짜다가 이 값이 유동성 공급사 시스템에도 나가는 값인지를 확인해 봤다. 우리 쪽에서만 쓰는 값이면 여기서 고치는 것으로 끝나기 때문이다.
확인해 보니 공급사 시스템에는 정책이 별도 엔티티로 없고 마켓 등록·수정 요청의 데이터에 값을 실어 받는 구조였다.
[우리] 정책 테이블 → 마켓이 참조
[저쪽] 마켓 데이터에 값이 박혀 있음
그러면 이미 나간 건에 대해서는 fee_policies 만 UPDATE 해서는 아무 일도 일어나지 않는다.
외부 시스템의 정책 표현
공급사 쪽에서 그 정책을 어떻게 다루는지를 봤더니 별도 항목으로 두고 참조하는 구조가 아니었다. 등록 요청에 실려 온 값을 그 마켓의 속성으로 그대로 복사해서 갖고 있었다.
즉 저쪽에는 우리 정책 테이블을 가리키는 연결이 없었다. 우리가 원본을 고쳐도 저쪽 사본은 그대로 남는 구조였다.
이미 등록된 것에는 안 닿는다
그래서 조치가 두 개로 나뉘었는데 fee_policies 를 UPDATE 하는 것과 이미 등록된 건을 다시 밀어 넣는 것이었다. 앞의 것만 하면 앞으로 등록될 건에만 맞는 값이 들어간다. 다시 미는 데도 바뀐 값만 PUT 하는 것과 마켓을 전부 재등록하는 것 두 가지 방법이 있었고 앞쪽을 골랐다. 이유는 재등록은 그 마켓의 호가를 잠시 비워서다.
다시 미는 대상이 몇 건인지를 알아야 작업 규모가 나오므로 공급사와 연동 상태로 GROUP BY 해 COUNT(*) 를 내 봤다.
등록 완료 → 갱신 작업 필요
예약 → 아직 안 갔으니 등록 시 자동 반영
미등록 → DB 수정만으로 충분
세 갈래였고 갱신 작업이 필요한 것은 등록 완료뿐이었다.
연동 상태로 갈리는 반영 필요
집계하다가 정책 테이블만 보고는 판단할 수 없다는 것이 드러났다. 그 테이블에는 값을 실어 나르는 대상이 지금 어느 상태인지가 없기 때문이다.
fee_policies 만 봤으면 등록이 끝난 건들을 미등록으로 오판할 뻔했다. 값이 사는 표와 값이 실려 가는 대상의 표를 JOIN 해야 조치 범위가 나온다.
참조가 복사로 바뀌는 경계
이 건의 요지는 시스템 경계를 넘어가면 참조가 복사로 바뀐다는 것이었다. 한 시스템 안에서는 원본 하나를 고치면 그것을 보는 곳이 전부 따라오는데 경계 밖에서는 그렇지 않다.
복사된 것은 다시 밀어야 맞춰지고 그 미는 작업이 조치의 절반을 차지한다. 다행히 쿼리를 돌리기 전에 알아서 두 조치를 한 번에 계획할 수 있었다.
정리
- 공급사 시스템은 정책을 별도 항목으로 안 두고 값으로 복사해 둘 수 있다
- 그러면
fee_policies의UPDATE가 이미 등록된 건에 반영되지 않는다 - 조치가
UPDATE와 갱신 작업 둘로 나뉜다 - 반영이 필요한지는 연동 상태로 갈린다
- 정책 테이블만 보면 등록 완료 건을 미등록으로 오판한다
- 값을 실어 나르는 대상의 표와
JOIN해서 본다 - 시스템 경계를 넘어가면 참조가 복사로 바뀐다
- 복사된 것은 다시 밀어야 맞춰진다