문제 상황

현재 입찰 요청을 보냈을 때 holdDeposit을 동기 REST로 진행했을 때 만약 결제 모듈이 죽었다면 서비스가 자연스럽게 실패하게 됩니다. 그래서 현재의 로직은 결제 모듈이 죽으면 입찰 관련된 사항이 올스톱이 되는 상황인데 이것에 대한 해결책을 찾은 와중에 문제가 생길 것 같아서 질문 드립니다.

A안

현재 원하던 방향은 Outbox + 비동기 보증금 홀드로

입찰 요청 → 입찰 저장 + BidDepositOutbox 저장 (같은 트랜잭션) → 스케줄러/Kafka가 비동기로 holdDeposit 호출

그 이후

성공 → Bid 상태 CONFIRMED 실패 → 재시도 or Bid 취소

입찰은 PENDING 상태로 먼저 저장하고 Payment 서비스가 복구되면 보증금 홀드 처리하는 식으로 하려고 생각하고 진행하였습니다. 그러나 현재가 롤백 로직을 고려했을 때 DEPOSIT_PENDING인 최고 입찰이 취소되면, 그 다음 CONFIRMED 입찰로 현재가를 되돌려야 하는 상황이 발생할 수 있을 거 같아서 고민중에 있습니다.

또 다른 문제로는 잔액이 부족한 사람이 입찰을 진행할 수 있는데 이것에 대한 문제도 있습니다.

T+0s A가 10만원 입찰 (잔액 0원, 하지만 DEPOSIT_PENDING으로 저장됨) 현재가: 10만원으로 갱신 T+5s B가 A의 입찰을 보고 12만원 입찰 T+10s 스케줄러: A의 holdDeposit 실패 → A 입찰 취소 현재가 롤백? 하지만 B가 이미 12만원 입찰함 → B 입장에서는 "10만원 입찰 때문에 12만원 넣었는데 그게 가짜였어?"

B안

또 다른 대안으로는

입찰 요청 → Bid(status=DEPOSIT_PENDING) 저장 + Kafka 이벤트 발행 → Payment 서비스가 컨슘 → holdDeposit 처리

그 이후 성공 이벤트 발행 → Bid(status=CONFIRMED) 실패 이벤트 발행 → Bid(status=CANCELLED) + 사용자 알림