한 처리 건이 사흘째 대기 상태로 멈춰 있다는 이야기가 들어왔다. 실패한 것도 아니고 끝난 것도 아닌 채였다.
Table of contents
Open Table of contents
증상 — 사흘째 대기
처리 커맨드의 매핑 함수를 열었다.
private function mappingOption($order)
{
$item = $this->findReturnItem($order->origin_item_id);
if (!$item) {
return ['result' => 'pending'];
}
...
}
findReturnItem 이 빈 값을 내면 그대로 대기를 반환한다.
이 건은 return_items 쪽 대응 항목이 애초에 없는 상태였다. $item 이 나중에 생기기를 기다리는 구조라서 끝이 없었다.
원인 — 시도 횟수가 안 늘었다
대기로 빠지는 자리를 더 봤다.
if ($result['result'] === 'pending') {
$order->status = 'pending';
$order->save();
return; // 시도 횟수 증가 없음
}
$order->status 만 pending 으로 바꾸고 시도 횟수는 건드리지 않은 채 빠져나간다.
보통은 시도가 쌓이면 한도를 넘어 실패로 빠지고 그때 알림이 나가거나 목록에 잡힌다. 여기서는 한도에 닿을 길이 없으니 아무 신호 없이 영원히 대기였다.
전체 흐름 — 왜 없는지의 경위
대응 항목이 왜 없는지 이력을 역추적했다.
1. 교환 접수 → 새 항목 생성
2. 그 항목이 결제 취소됨
3. 외부가 재교환 가주문을 다시 만듦
4. 새 항목에 대한 클레임이 없음
5. 매핑 실패 → 영원히 대기
두 번째 줄의 결제 취소 가 관건이었다.
교환으로 생긴 항목이 취소되면 거기에 딸린 클레임 도 함께 정리된다. 그 뒤에 외부가 가주문을 다시 만들면 새 항목에는 클레임이 없는 상태로 넘어온다.
검증 — 같은 패턴을 세었다
이 건 하나만인지 확인했다.
대기 상태로 방치 4건 이상
오류 상태 수천 건
대기 쪽에 수개월 방치된 것들이 섞여 있었다.
오류 는 그래도 집계에 잡히는데 대기 는 아무 데도 안 잡힌다. 정체된 건을 만나면 그 항목에 대응하는 레코드가 있는지부터 본다는 순서를 그때 정했다.
SELECT COUNT(*) FROM return_items WHERE order_item_option_id = ?;
COUNT(*) 가 0이면 이 유형이다.
선택지 — 세 가지 해결 방향
수동 해결 방향을 셋으로 정리했다.
① 외부에서 가주문 취소 원인 쪽을 정리한다
② 상태를 오류로 강제 전환 대기에서 빼서 목록에 잡히게 한다
③ 수동으로 레코드 생성 없는 것을 만들어 진행시킨다
① 이 가장 깨끗하지만 외부 관리 화면에서 해야 한다.
③ 이 가장 위험했다. 실제로 없는 데에는 이유가 있는데 그 이유를 모른 채로 만드는 것이다.
대응 — 보이게 만드는 것이 먼저
② 를 우선으로 봤다.
① 은 외부 협조가 필요
③ 은 없는 데이터를 만드는 것
② 는 우리 안에서 되고, 보이게 만든다
대기 는 보이지 않는 것이 문제라서 오류 로 바꾸면 최소한 집계에 잡힌다.
대기 라는 말은 곧 될 것이라는 뜻으로 읽힌다. 될 조건이 영영 안 생기는 건이 그 상태로 남아 있으면 그 표시 자체가 거짓 신호다.
근본은 따로 적어 두었다.
대응 레코드 없음
↓
시도 횟수 증가
↓
한도 초과 시 오류로 전환
곧 될 대기와 영영 안 될 대기를 시도 횟수로 가르는 것이다.
몇 번 시도해도 안 되면 그것은 대기가 아니라 문제다. 그 구분이 코드에 없으면 상태 이름이 실제 상황과 어긋난 채로 남는다.
정리
- 대응 레코드가 없으면 대기 상태로 영원히 멈출 수 있다
- 기다림에 끝이 없는 구조가 만들어진다
- 시도 횟수가 안 늘면 한도로 못 빠지고 신호가 없다
- 오류는 집계에 잡히지만 대기는 안 잡힌다
- 이력을 역추적하면 왜 없는지 시나리오가 나온다
- 정체되면 대응 레코드 존재 여부를 먼저 확인한다
- 해결은 원인 정리와 오류 전환과 수동 생성 셋이다
- 없는 레코드를 만드는 것이 가장 위험하다
- 오류 전환이 현실적이고 최소한 보이게 된다
- 대기는 곧 될 것이라는 뜻이라 영영 안 되면 거짓 신호다
- 근본은 시도 횟수를 늘려 한도로 빠지게 하는 것이다