테마
Story: Exclusive Lock 시스템 구현
메타
| 항목 | 값 |
|---|---|
| Story ID | E-05-S-01 |
| Epic | E-05 연동 자동화 |
| 상태 | ready-for-dev |
| 우선순위 | P0 |
| 규모 | M |
| 담당 개발자 | 하록 (BE) |
사용자 스토리
As a 시스템 관리자,
I want SMS 인증 단계에서 한 번에 한 명의 셀러만 진행되도록 Lock을 관리하고 싶다,
So that SMS 매칭이 100% 정확하게 이루어진다.
수락 기준 (Acceptance Criteria)
AC-01: Lock 획득
| 항목 | 내용 |
|---|---|
| Given | Lock이 FREE 상태일 때 |
| When | 셀러가 "준비 완료" 버튼을 클릭하면 |
| Then | 해당 셀러가 Lock을 획득한다 |
| And | 2분 타이머가 시작된다 |
AC-02: Lock 대기
| 항목 | 내용 |
|---|---|
| Given | 다른 셀러가 Lock을 보유 중일 때 |
| When | 새 셀러가 "준비 완료"를 클릭하면 |
| Then | 대기열에 추가되고 예상 대기 시간이 표시된다 |
AC-03: Lock 자동 해제 (타임아웃)
| 항목 | 내용 |
|---|---|
| Given | Lock을 보유 중인 상태에서 |
| When | 2분이 경과하면 |
| Then | Lock이 자동으로 해제된다 |
| And | 대기열의 다음 셀러가 Lock을 획득한다 |
AC-04: Lock 수동 해제
| 항목 | 내용 |
|---|---|
| Given | Lock을 보유 중인 상태에서 |
| When | 인증이 완료되거나 셀러가 취소하면 |
| Then | Lock이 즉시 해제된다 |
AC-05: 동시 요청 처리
| 항목 | 내용 |
|---|---|
| Given | 동시에 여러 셀러가 Lock을 요청할 때 |
| When | 요청이 처리되면 |
| Then | Atomic 연산으로 정확히 1명만 Lock을 획득한다 |
태스크 분해
Task 1: Lock 데이터 모델 AC-01~AC-05
- [ ] 1.1: Redis 기반 Lock 구조 설계
- Key:
integration:lock - Value:
{session_id, seller_id, locked_at, expires_at}
- Key:
- [ ] 1.2: 대기열 구조 설계
- Key:
integration:queue - Type: List (FIFO)
- Key:
Task 2: Lock API AC-01, AC-02, AC-04
- [ ] 2.1: POST /api/integration/lock - Lock 획득 요청
- [ ] 2.2: DELETE /api/integration/lock - Lock 해제
- [ ] 2.3: GET /api/integration/lock/status - Lock 상태 조회
Task 3: 타임아웃 처리 AC-03
- [ ] 3.1: Lock 만료 스케줄러 (매 1초 체크)
- [ ] 3.2: 만료 시 자동 해제 + 대기열 처리
Task 4: 동시성 제어 AC-05
- [ ] 4.1: Redis SETNX 기반 atomic lock
- [ ] 4.2: 락 획득 실패 시 대기열 추가
Lock 상태 머신
LOCK_FREE ──────────────────────────────────────┐
│ │
│ 셀러 "준비 완료" 클릭 │
▼ │
LOCKED (seller_id, 2분 타이머) │
│ │
├── SMS 수신 완료 ────────── Lock 해제 ────┤
├── 2분 타임아웃 ─────────── Lock 해제 ────┤
└── 셀러 취소 ────────────── Lock 해제 ────┘Dev Notes
Redis 명령어 예시
redis
# Lock 획득 (atomic)
SETNX integration:lock "{session_id, seller_id, ...}"
EXPIRE integration:lock 120 # 2분
# 대기열 추가
RPUSH integration:queue "{session_id, seller_id, ...}"
# 대기열에서 꺼내기
LPOP integration:queueAPI 응답 예시
json
// Lock 획득 성공
{
"status": "locked",
"session_id": "uuid",
"expires_in": 120
}
// Lock 대기
{
"status": "waiting",
"queue_position": 2,
"estimated_wait": 180
}생성일: 2026-01-20
