경매 서비스는 평소에는 조용하다가 마감 직전 몇 초에 모든 일이 몰립니다. 풀잎바다와 툴툴이를 만들면서 가장 신경 쓴 부분이 이 구간이었습니다.
왜 어려운가
두 사람이 거의 동시에 입찰한다고 해봅시다. A가 10만 원, B가 11만 원을 부릅니다. 서버가 이 둘을 동시에 처리하면 이런 일이 생길 수 있습니다.
- 둘 다 “현재 최고가 9만 원”을 읽습니다.
- 둘 다 “내 금액이 더 높다”고 판단합니다.
- 둘 다 성공 처리됩니다.
- 최종 최고가가 10만 원으로 남습니다.
11만 원을 부른 B가 졌습니다. 사용자 입장에서는 이해할 수 없는 일이고, 한 번 겪으면 그 서비스를 못 믿습니다.
돈이 걸린 순서 문제는 “거의 안 생긴다”로는 부족합니다. 아예 생길 수 없게 만들어야 합니다.
해결 1. 읽고 쓰는 걸 한 덩어리로
핵심은 “현재 최고가를 읽는 것”과 “새 최고가를 쓰는 것” 사이에 다른 사람이 끼어들지 못하게 하는 것입니다.
데이터베이스에는 이걸 위한 장치가 있습니다. 해당 경매 건에 잠금을 걸고, 확인과 기록을 한 번에 끝낸 뒤 풀어줍니다. 그러면 입찰이 아무리 몰려도 한 명씩 차례로 처리됩니다.
잠금 범위를 넓게 잡으면 전체가 느려지니, 딱 그 경매 한 건에만 겁니다.

해결 2. 시간은 서버 기준으로
마감 시각을 사용자 기기 시계로 판단하면 안 됩니다. 기기 시계는 사람마다 조금씩 다릅니다. 몇 초 차이로 낙찰이 갈리는 서비스에서는 이게 분쟁이 됩니다.
그래서 남은 시간은 서버가 계산해서 내려주고, 앱은 받아서 보여주기만 합니다. 화면의 카운트다운은 참고용이고, 실제 마감 판정은 서버가 합니다.
해결 3. 마감 직전 입찰은 시간을 늘립니다
경매에서 흔히 쓰는 방식입니다. 마감 10초 전에 입찰이 들어오면 마감을 조금 미룹니다.
이건 기술 문제가 아니라 공정성 문제입니다. 마지막 순간에 눌러서 이기는 방식이면, 네트워크가 빠른 사람이 유리해집니다. 시간을 늘려주면 서로 값으로 겨루게 됩니다.

해결 4. 기록을 다 남깁니다
누가 언제 얼마를 불렀는지 전부 남깁니다. 최고가만 저장하면 나중에 분쟁이 생겼을 때 설명할 방법이 없습니다.
기록이 있으면 “몇 시 몇 분 몇 초에 이 금액이 들어왔습니다”라고 정확히 답할 수 있습니다. 거래 서비스에서는 이 근거가 기능만큼 중요합니다.
정리
- 확인과 기록을 한 덩어리로 처리해 순서를 보장합니다.
- 시간 판정은 무조건 서버가 합니다.
- 마감 직전 입찰에는 시간을 조금 늘려줍니다.
- 입찰 내역을 전부 남겨 근거를 만듭니다.
경매는 화면이 단순해서 쉬워 보이지만, 안 보이는 곳에서 정확도를 지키는 일이 대부분입니다.
