기술 회고

[기술 회고] 실시간 경매 마감 처리와 동시성·트랜잭션 개선

sybear02 2026. 7. 27. 13:43

실시간 경매 마감 처리와 동시성·트랜잭션 개선

이 글은 부트캠프 3차 미니 프로젝트 MACTA 백엔드에서, 마감 직전 입찰 충돌과 종료 스케줄러·알림 경로를 어떻게 다듬었는지 정리한 기술 회고다. 팀장을 맡아 ERD·API 명세와 작업 기준을 맞추는 일도 함께 진행했다.

프로젝트와 동작 원리

MACTA는 트래픽과 보안 위협을 고려한 실시간 경매 플랫폼이다. 백엔드는 상품·입찰·결제·알림·스케줄러가 한 상태로 맞물린다. 입찰이 들어오면 최고가와 이력이 갱신되고, 마감 시각이 되면 스케줄러가 종료 처리를 하며, 그 과정에서 알림과 결제 검증이 이어진다.

동시성의 핵심은 “한 건씩 순서대로만 오면 된다”가 성립하지 않는다는 점이다. 마감 직전에는 요청이 겹친다. 같은 순간에 두 입찰이 들어오거나, 종료 처리와 입찰이 겹치면 최고가나 상태가 어긋날 수 있다. 트랜잭션 격리와 스케줄러 설계가 기능 구현만큼 중요해지는 지점이다.

무엇이 문제였나

정상 시나리오만 보면 입찰·종료·알림이 동작하는 것처럼 보여도, 마감 직전 충돌을 가정하지 않으면 구멍이 남는다. 종료 스케줄러와 이벤트 리스너가 중복되거나, 알림 경로가 어긋나면 판매자·구매자 쪽 상태가 다르게 보인다. UTC와 KST 시간 차가 있으면 마감 시각 자체가 밀리거나 당겨진다.

팀으로 만들 때는 기준이 흔들리기 쉬운 구간에서 의견이 갈렸다. 트랜잭션 격리, 알림 경로, 시간 동기화처럼 “맞게 보이지만 정의가 다른” 문제들이었다. 구현만 늘리면 충돌이 늘고, 문서와 테스트 기준이 필요했다.

실제로 어떻게 개선했나

동시성과 종료 스케줄러

마감 직전 입찰이 겹치는 상황을 가정하고 동시성 테스트를 넣었다. 경매 종료 스케줄러에는 트랜잭션 격리를 적용하고, 장애에 대한 방어 로직과 트랜잭션 분리도 다듬었다. AuctionEventListener 중복을 정리하고 비동기 트랜잭션 쪽도 손봤다. “종료가 한 번만, 일관된 상태로” 끝나게 만드는 쪽이 목표였다.

결제·상태 검증

결제 전에는 금액·권한·상태 검증을 두었다. 입찰·결제·거래 API에서 하드코딩된 인증 가정을 줄이고 검증 로직을 맞추는 작업도 있었다. 실시간 도메인에서는 성공 응답 하나가 곧 돈과 신뢰로 이어지므로, 상태 머신을 건너뛴 처리가 위험했다.

시간·알림·보안

UTC/KST 차이로 마감이 어긋나는 문제를 잡고, 직렬화·스케줄러 쪽 시간 처리를 맞췄다. 입찰 시 판매자 알림 누락, 알림 경로 오류, 비동기 알림 처리도 이어서 수정했다. JWT·Security 하드닝과 예외 처리 강화도 진행했다. 기능 추가만큼 기본 보안·운영 이슈가 백엔드 신뢰에 직접 영향을 줬다.

API와 팀 기준

마이페이지 목록·입찰·관심 경매 조회와 페이지네이션, 메인 통계 API, 경매 상세 필드 보강, live bidding activity 반영 같은 API 작업도 이어졌다. 팀장으로서 ERD·API 명세와 작업 규칙을 먼저 정리하고, 인증·입찰·알림·스케줄러 PR을 리뷰·머지하며 일정을 맞췄다. 기준이 갈리는 구간은 이슈로 남겨 “무엇으로 판단할지”를 합의했다.

정리

MACTA에서 오래 붙잡았던 건 화면용 CRUD가 아니라, 마감 직전에도 상태가 깨지지 않게 만드는 일이었다. 동시성 테스트, 스케줄러 트랜잭션 격리, 결제 전 검증, 시간 동기화, 알림 경로, 보안 하드닝을 같이 봐야 했다. 실시간 경매는 정상 경로보다 겹치는 경로를 먼저 적어야 한다는 감각이 남았다.

다음에 다시 한다면 동시성 시나리오 목록을 명세 초기에 고정하고, 스케줄러·이벤트·알림의 순서도를 테스트와 한 세트로 두고 시작하고 싶다.

관련 코드: https://github.com/owhat02/backend-macta