일기 slecs

연락처 송금 자동 매칭 누락으로 쌓이던 PENDING 건 해소

목차

연락처 송금 매칭, 왜 다시 손댔나

연락처 기반 송금 흐름에서 입금자명/금액으로 자동 매칭하는 로직이 돌고 있는데, 큐에 들어온 건이 실제로 수령됐는지 확인하는 단계가 비어있었음. 매칭은 됐는데 수령 확인이 누락돼서 PENDING으로 남아있는 건들이 쌓였고, 운영팀이 손으로 정리하고 있던 상태.

원인은 두 가지였음.
- 매칭 유틸이 입금 레코드 상태만 보고 종료
- 큐 측에서 수령 콜백을 받아도 매칭 테이블에 반영이 안 됨

리팩터링 포인트

매칭 유틸과 송금 유틸을 분리함. 책임 경계가 모호해서 호출 순서가 뒤섞이고 있었음.

모듈 역할
매칭 로직 입금자명 + 금액 + 시간 윈도우로 후보 산출
송금 유틸 큐 조회 → 매칭 호출 → 수령 확인 → 상태 갱신
SQL 후보 추출 + 수령 플래그 업데이트

수령 확인은 단순한 플래그 토글이 아니라, 큐의 시퀀스와 입금 레코드의 매칭 ID를 양방향으로 묶어줘야 했음. 안 그러면 같은 입금 건이 두 번 매칭될 수 있음.

update queue
   set received_yn = 'Y',
       match_id   = #{matchId},
       received_at = now()
 where queue_seq  = #{queueSeq}
   and received_yn = 'N'

received_yn = 'N' 조건이 핵심. 동시성 환경에서 한 건이 두 번 처리되면 안 되니 update 자체를 락으로 사용함. 별도 비관 락 안 걸고 처리량 유지.

검증하면서 걸린 것들

  • 매칭 후보가 0건일 때 NPE 한 번 잡힘. Optional 안 쓰고 null 반환하는 옛날 패턴이 살아있었음
  • 시간 윈도우를 ±10분으로 잡았는데, 실거래에서 입금 지연이 30분 넘는 케이스가 있어서 1시간으로 조정
  • 매칭 ID 타입이 한쪽은 string, 한쪽은 long. 캐스팅 누락으로 매칭 안 잡히는 건 발견해서 보정

회고

리팩터링하면서 느낀 건, 큐와 매칭은 분리된 컴포넌트지만 상태는 양쪽이 합의해야 한다는 점. 한쪽만 갱신되면 무조건 정합성 깨짐. update의 where 조건을 안전장치로 쓴 게 핵심이었고, 다음에 비슷한 큐 처리 로직 짤 때 템플릿으로 재활용할 만함.

운영팀 수동 처리 건수가 일주일 만에 0으로 떨어짐. 끝

댓글 0

첫 댓글 달아줘.