목적
- 주문 처리 경로를 비동기 단일 파이프라인으로 통일
- 동시성 직렬화 메커니즘 중복 제거 (마켓 큐 + ReentrantLock → 큐 단일화)
- "주문이 어떻게 처리되는가"가 한 문장으로 설명되는 구조 확보
배경
현재 주문 처리에 동일 목적(마켓 단위 직렬화)의 메커니즘이 2개 공존한다.
MarketOrderCommandQueue — 마켓당 워커 스레드 1개 (single-writer)
MarketOrderLockManager 의 ReentrantLock — 프로세서 내부에서 추가 획득
워커 스레드가 마켓당 1개이므로 동기 생성 경로에서 락은 사실상 경합되지 않는다. 락이 실제로 의미를 갖는 곳은 큐를 거치지 않고 HTTP 스레드에서 오더북을 직접 변경하는 취소 경로 뿐이다. 그 결과:
- 직렬화 메커니즘이 두 곳에 분산되어 "무엇이 동시성을 보장하는가"가 불명확
- 진입 경로가 3개(동기 생성 / 비동기 생성 / 취소)이고 각자 락·트랜잭션·오더북 반영 로직이 미묘하게 다른 중복 구조
SyncOrderProcessor 와 AcceptedOrderProcessor 의 매칭/정산/afterCommit 로직 복붙
releaseRegistered + afterCommit/afterCompletion 이중 해제 등 락 수명 관리 복잡도
비동기 경로는 이미 주문을 ACCEPTED로 DB 선저장 후 처리 + 미처리분 복구 스케줄러(AcceptedOrderRecoveryScheduler)를 갖추고 있어 유실 방어가 가능하다. 따라서 비동기를 단일 정식 경로로 승격한다.
작업 범위
제거
- 마켓 락 3종:
MarketOrderLockManager, MarketOrderLockService, MarketOrderLockScope
- 동기 생성 경로:
POST /orders 동기 엔드포인트, OrderService.createOrder(), SyncOrderProcessor
- 큐의 블로킹
submit/await 중 동기 생성 전용 사용처
유지/승격
POST /orders → 비동기 접수 경로로 단일화 (기존 /orders/async 동작을 정식 경로로)
AcceptedOrderService / AcceptedOrderProcessor 를 주문 처리 표준 핸들러로
AcceptedOrderRecoveryScheduler (유실 방어 안전망) 유지
MatchingEngine, 정산, 오더북 복구 유지
취소 경로
- 취소를 마켓 큐를 거치도록 변경하여 오더북 변경 주체를 워커로 단일화
- 사용자 응답은 즉시 반환 유지 (취소 한정 블로킹
submit 사용)
완료 기준
- 마켓 락 관련 클래스/참조 전부 제거
- 오더북을 변경하는 주체가 마켓 워커 스레드로 단일화
- 주문 생성/취소가 동일 큐를 통과
- 기존 주문/취소 응답 계약 유지
./gradlew test 통과 (비동기 관련 테스트 정리 포함)
후속 작업
SyncOrderProcessor/AcceptedOrderProcessor 잔여 중복 → 단일 핸들러로 통합
- 라인 단위 계측(
OrderCreateStageRecorder 등) 경계 단위로 축소
- 설계 의사결정 문서화 (single-writer 채택 이유, 동기 영속화 트레이드오프, 유실 방어 메커니즘)
목적
배경
현재 주문 처리에 동일 목적(마켓 단위 직렬화)의 메커니즘이 2개 공존한다.
MarketOrderCommandQueue— 마켓당 워커 스레드 1개 (single-writer)MarketOrderLockManager의ReentrantLock— 프로세서 내부에서 추가 획득워커 스레드가 마켓당 1개이므로 동기 생성 경로에서 락은 사실상 경합되지 않는다. 락이 실제로 의미를 갖는 곳은 큐를 거치지 않고 HTTP 스레드에서 오더북을 직접 변경하는 취소 경로 뿐이다. 그 결과:
SyncOrderProcessor와AcceptedOrderProcessor의 매칭/정산/afterCommit 로직 복붙releaseRegistered+ afterCommit/afterCompletion 이중 해제 등 락 수명 관리 복잡도비동기 경로는 이미 주문을
ACCEPTED로 DB 선저장 후 처리 + 미처리분 복구 스케줄러(AcceptedOrderRecoveryScheduler)를 갖추고 있어 유실 방어가 가능하다. 따라서 비동기를 단일 정식 경로로 승격한다.작업 범위
제거
MarketOrderLockManager,MarketOrderLockService,MarketOrderLockScopePOST /orders동기 엔드포인트,OrderService.createOrder(),SyncOrderProcessorsubmit/await중 동기 생성 전용 사용처유지/승격
POST /orders→ 비동기 접수 경로로 단일화 (기존/orders/async동작을 정식 경로로)AcceptedOrderService/AcceptedOrderProcessor를 주문 처리 표준 핸들러로AcceptedOrderRecoveryScheduler(유실 방어 안전망) 유지MatchingEngine, 정산, 오더북 복구 유지취소 경로
submit사용)완료 기준
./gradlew test통과 (비동기 관련 테스트 정리 포함)후속 작업
SyncOrderProcessor/AcceptedOrderProcessor잔여 중복 → 단일 핸들러로 통합OrderCreateStageRecorder등) 경계 단위로 축소