저장 요청이 실패해 보여도 서버에는 이미 주문이 남아 있을 수 있습니다. n8n 2.40.7에서 저장 직후 응답을 두 번 잃게 하자, 저장 노드가 세 번 요청했고 같은 주문이 세 행으로 남았습니다. 준비 노드는 한 번만 실행됐습니다.
같은 재시도 설정인데 결과가 달라진 이유
| 시험 조건 | 저장 요청 | 최종 저장 |
|---|---|---|
| 정상 응답 | 1회 | 1행 |
| 저장 전 503 두 번 | 3회 | 1행 |
| 저장 후 응답 유실 두 번 · 매번 INSERT | 3회 | 3행 |
| 저장 후 응답 유실 두 번 · UNIQUE 키 | 3회 | 1행 |
| 같은 키·다른 금액 재전송 | 3회 · 409 충돌 | 기존 1행·100 유지 |
가상 주문 ORDER-0001, 금액 100, HTTP Request의 Retry On Fail 및 Max Tries 3 조건입니다. 첫 네 조건은 각각 별도 시험이며, 마지막 충돌은 UNIQUE 저장소에 금액 200을 보낸 시험입니다. 2026년 9월 29일 실제 실행·SQLite 행을 읽은 기록을 10월 5일 다시 대조했습니다. 각 조건 1회 관찰로, 장애 발생률이나 처리 성능을 추정한 결과가 아닙니다.
해결 지점은 앞 노드가 아니라 저장 계약입니다
실험의 UNIQUE 키는 (case_id, order_id)입니다. 같은 키·같은 내용은 기존 저장 결과를 돌려주고, 같은 키·다른 내용은 409로 거절했습니다. 재시도 때 새 ID를 만들면 다른 주문으로 처리될 수 있으므로 원래 업무의 키를 유지해야 합니다. “있는지 조회한 뒤 INSERT”를 별도로 수행하는 방식과 DB의 원자적인 유일성 제약은 같지 않습니다.
409도 예제 설정에서는 세 번 요청됐습니다. 데이터 충돌은 기다린다고 해결되지 않으므로 운영에서는 자동 재시도 대상에서 분리해 검토해야 합니다. 이 시험의 저장 API를 그대로 운영에 배포하는 것은 권하지 않습니다. 인증, 접근 권한, 동시성, 키 보관 기간과 외부 결제·메일 처리까지 구현한 서비스가 아닙니다.
내 자동화에 적용하기 전 확인할 네 가지
- 응답이 끊긴 요청의 업무 키로 저장소를 조회합니다. HTTP 오류만 보고 같은 주문을 새 키로 만들지 않습니다.
- 정상 응답, 저장 전 실패, 저장 후 응답 유실을 각각 시험합니다. 요청 로그와 저장 행 수를 따로 적습니다.
- 같은 내용의 재전송은 기존 결과를 유지하고, 다른 내용의 재전송은 원본을 덮어쓰지 않는지 확인합니다.
- 다음 실행에서도 같은 업무 키를 유지하는지 확인합니다. 실험에서는 같은 주문의 새 CLI 실행 뒤에도 한 행이 남았습니다.
재현 자료와 예상 결과
Docker Desktop이 있는 환경에서 ZIP을 새 빈 폴더에 풀고 README의 PowerShell 명령을 실행합니다. 기존 n8n 데이터 폴더를 사용하지 않습니다. 네트워크가 없는 컨테이너에서 다섯 워크플로를 가져와 여섯 번 실행하며, 포트를 공개하거나 예약을 활성화하지 않습니다.
| 결과 파일에서 찾을 값 | 확인 기준 |
|---|---|
| writes의 lost-unsafe | 동일 주문 3행 |
| safe_writes의 lost-safe | 1행, amount=100 |
| events의 payload-conflict | 금액 200 요청이 거절됨 |
| prepare와 store 이벤트 | 준비 1회여도 저장 요청은 3회 가능 |
ZIP의 기존 결과 DB를 덮어쓰는 실행은 차단되므로 재시험은 새 빈 폴더를 사용합니다. 실행 실패 시 환경·노드·민감값을 지운 오류를 기록하고 위 기준과 비교하세요. n8n 화면의 Retry execution 버튼, Cloud, queue mode, 동시 요청은 이 실험에서 시험하지 않았습니다. UI Retry를 “항상 처음부터 재실행”이라고 일반화하지 않습니다.
관련 실험: 빈 입력과 0원 주문 · API 필드 호환 시험
작성·실험 정리: HEYDLIFE 운영자와 AI 작성 보조. 개정: 2026년 10월 5일. 가상 자료로 수행한 시험과 실제 서비스 사용 성과를 구분했습니다.