금융 전송 중복 실행 사고 대응
처리 지연 중 동일 거래가 큐에 중복 적재된 사고를 재현하고, 적재와 소비 단계의 상태 검증을 함께 수정했습니다.
Java, SQL, Batch Update, Integration Test
응답 지연을 실패로 판단한 재시도가 중복 실행으로 이어졌습니다
전송 데이터를 수집하면서 데이터별 검증 조회를 반복해, 처리 건수가 늘어날수록 조회 횟수와 처리 시간도 함께 늘었습니다. 브라우저가 응답하지 않자 사용자가 새 브라우저에서 같은 거래를 다시 요청했고, 서버는 두 요청을 큐에 모두 넣었습니다. 큐에서 전송을 시작할 때도 최신 처리 상태를 확인하지 않아 동일 거래가 두 번 실행됐습니다. 이 사고는 안정화 기간에 전송 흐름을 지켜보던 중 발견했습니다.
재요청은 응답을 받지 못한 사용자가 할 수 있는 정상적인 행동입니다. 직접 원인은 같은 업무 요청을 큐에 다시 넣을 수 있었던 점이고, 실제 중복 실행으로 이어진 이유는 소비 단계에도 상태 검증이 없었기 때문입니다.
적재와 소비 단계에 나눈 방어
중복 적재와 소비 단계의 최신 상태 미확인이 각각 사고 원인이었기 때문에 한쪽만 바꾸지 않고 두 경계를 함께 수정했습니다.
전송 요청을 큐에 넣기 전에 처리 상태를 먼저 변경하도록 순서를 바꿨습니다. 큐 소비자는 저장된 데이터를 다시 조회하고 현재 상태를 확인한 뒤 외부 전송 여부를 결정하도록 수정했습니다. 같은 사용자의 같은 업무 전송이 진행 중이면 추가 실행도 막았습니다.
누적 데이터 처리 경로 변경
처리 지연을 만들던 반복 조회도 함께 수정했습니다. 반복문 안에서 데이터 한 건마다 검증 정보를 조회하던 구조를 필요한 데이터를 한 번에 가져와 검증하는 방식으로 바꾸고, 여러 UPDATE는 batch로 처리했습니다. 조회와 갱신에 사용하는 인덱스도 수정했습니다.
영향 범위에 따라 나눈 배포
전송 때마다 발급하던 전문 번호를 수집 단계에서 미리 부여하고, 전송 성공 뒤 사용 상태를 기록하는 보조 검증도 추가했습니다. 이 변경은 영향 범위와 테스트 부담이 더 커 사고 직후 패치와 분리했고, 별도로 검증한 뒤 운영에 반영했습니다.
장애 재현과 운영 확인
처리가 끝나기 전에 같은 거래를 다른 브라우저에서 다시 요청하는 흐름으로 사고를 재현했습니다. 변경 후 같은 시나리오에서 중복 전송이 일어나지 않는 것을 확인하고 운영 환경에 배포했습니다.
수정 전략과 테스트 결과는 팀에 공유했고, 같은 수정을 다른 업체 환경에도 순차 적용했습니다.
2주 동안 관찰했고 같은 중복 실행은 다시 나타나지 않았습니다.