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