마이그레이션 뒤에 잘못 남은 값을 정리하는 배치를 만들어야 했고 대상이 수천 건이라 화면으로는 안 됐다. 바로 짜지 않고 화면으로 같은 값을 고칠 때 무엇이 남는지를 먼저 봤다.
Table of contents
Open Table of contents
정상 경로가 남기는 여섯 종류
수정 요청 하나가 본체 갱신과 변경 이력과 수정 이력과 가격 이력과 수수료율과 전송 작업까지 남기고 있었다. 내가 짜려던 배치는 그중 첫 번째만 한다.
나머지 다섯이 안 남으면 같은 값이지만 다른 상태가 된다. 우회하는 배치는 무엇을 안 하게 되는지를 먼저 세어야 하고 그것은 정상 경로를 따라가야 나온다.
계층에 따라 남는 것이 달랐다
더 보니 상위와 하위가 다르게 동작하고 있었다. 상위는 앞의 셋만 남기고 뒤의 셋은 하위에서만 남았다.
이유를 찾아보니 가격 이력을 쓰는 함수 자체는 조건을 안 보는데 호출하는 쪽이 하위일 때만 부르고 있었다. 함수만 읽으면 이 조건이 안 보이고 호출부를 봐야 드러난다.
상위 변경이 하위로 전파되는 구조
그러면 상위의 가격 변경은 어떻게 기록되는지가 남는다. 상위를 고치면 하위로 전파되고 각 하위에서 그 함수가 호출된다.
즉 상위에는 안 남고 하위에만 남는 것이 정상 상태였다. 이것을 모르고 상위에도 남기면 정상 경로가 만들지 않는 행을 배치가 만들게 된다.
계층으로 분기한 배치
그래서 배치를 계층으로 갈라 상위는 셋만 남기고 하위는 다섯을 남기게 했다. 전송 작업만 일부러 뺐는데 이 정리는 외부에 알릴 성격이 아니었기 때문이다.
뺀 것도 판단해서 뺀 것이므로 그 사실과 이유를 주석에 적었다. 안 적으면 다음 사람이 누락으로 보고 채워 넣는다.
안 맞췄을 때 깨지는 가정
상위에도 가격 이력을 남겼다면 당장은 아무 일도 안 생긴다. 그러나 그 테이블을 읽는 코드가 상위에는 없다는 것을 전제하고 있으면 그 조회가 틀린 결과를 낸다.
검증은 같은 변경을 화면으로 한 번 배치로 한 번 하고 각 테이블의 행 수와 값을 대조하는 방식으로 했다. 이 대조에서 두 군데를 고쳤는데 이력의 형식이 미묘하게 달라서 눈으로는 안 보였다.
정리
- 서비스 계층을 우회하는 배치는 정상 경로가 남기는 것을 먼저 센다
- 계층에 따라 남는 것이 다를 수 있다
- 함수가 아니라 호출부가 조건을 걸기도 한다
- 상위 변경이 하위로 전파되면서 기록되는 구조가 있다
- 배치를 계층으로 분기해 정상 경로와 같은 상태를 만든다
- 일부러 뺀 것은 이유와 함께 주석에 적는다
- 정상 경로가 안 만드는 데이터를 만들면 읽는 쪽의 가정이 깨진다
- 검증은 화면으로 한 번 배치로 한 번 하고 결과를 대조한다