개발 slecs

가상계좌 웹훅 데드락을 멱등성과 잠금 순서 통일로 해결

목차

가상계좌 충전 웹훅에서 발생하던 데드락 문제를 근본적으로 해결했음.

문제 상황

가상계좌 입금 알림(웹훅)이 동시에 여러 건 들어올 때 데이터베이스 데드락이 발생하고 있었음. 결제대행사에서 웹훅을 재전송하면서 같은 거래가 중복 처리될 위험도 있었음. 데드락은 재현이 타이밍에 의존해서 로컬에서는 잘 안 나타나고 운영에서만 간헐적으로 발생했음.

데드락 발생 원리

트랜잭션 A (웹훅 요청 1):
  충전 테이블 락 획득 → 잔액 테이블 락 대기 중

트랜잭션 B (웹훅 요청 2):
  잔액 테이블 락 획득 → 충전 테이블 락 대기 중

→ 서로 상대방의 락을 기다리며 교착 상태

잠금 획득 순서가 코드 경로마다 달랐기 때문에 발생한 문제임.

해결 방법

  1. 잠금 순서 통일: 모든 경로에서 동일한 순서로 락 획득
  2. 멱등성 키: 같은 웹훅이 여러 번 와도 한 번만 처리 (unique constraint)
  3. 재시도 로직 제거: 불필요한 재시도가 오히려 경쟁을 심화시켰음

교훈

데드락 해결의 핵심은 항상 일관된 순서로 자원을 잠그는 것임. 코드 리뷰 시 잠금 순서를 명시적으로 문서화하면 나중에 다른 개발자가 잘못된 순서로 코드를 추가하는 것을 방지할 수 있음.

다음

작업 후기

사내 서비스를 만들다 보면 기능 하나가 단순히 화면에 버튼 하나 추가하는 것으로 끝나지 않는다는 걸 계속 체감함. SQL 집계, 상태 머신, 예외 처리, 화면 렌더링, 권한 체크가 모두 엮여 있어서 어느 하나만 빠뜨려도 숫자가 맞지 않거나 특정 사용자에게 이상한 화면이 나타남.

특히 금융/결제 도메인은 숫자 하나가 틀리면 신뢰가 무너질 수 있어서 꼼꼼함이 기본값이어야 함. "대충 맞는 것 같다"로 넘어가면 나중에 반드시 다시 돌아옴.

개발 방식

  • 변경 전 현재 동작 스크린샷이나 수치 메모
  • 수정 후 같은 케이스로 확인
  • 관련 화면이 있으면 숫자 cross-check
  • 커밋 메시지는 "무엇을" 보다 "왜"를 담으려고 노력

작은 커밋을 자주 하면 문제가 생겼을 때 어느 변경에서 깨졌는지 찾기 훨씬 쉬움. 그래서 논리적으로 독립된 단위로 커밋을 쪼개는 습관을 유지 중.

다음

댓글 0

첫 댓글 달아줘.