
결국 같은 자원에 여러 스레드(메서드)가 접근해서 데이터를 수정하려고 해서 생기는 일
이 동시성 문제를 해결하기 위해:
핵심 해결 과제: 데이터가 수정된 것이 확정되기 전에 또 다른 스레드가 데이터를 수정하지 못하도록 해야한다
결과: 동시성 문제로 재고 불일치 발생
ExecutorService pool = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors() * 2
);
이유:
deadline과 retrial time을 둘 다 설정해 준 이유:
서로 보완하는 효과가 있음
deadline → 최대 총 대기 시간을 제어
: 시스템 응답성을 보장 예) 4초 이상 블록되지 않음.
MAX_RETRY_COUNT → 과도한 재시도를 방지
: Redis에 불필요한 요청 폭주를 막고, 로드나 대기 부하를 줄임
┌─────────────────┐
│ Lock 요청 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ setIfAbsent() │
└────────┬────────┘
│
┌────┴────┐
│ 성공? │
└────┬────┘
│
Yes │ No
┌────┴────┐
│ │
▼ ▼
┌───────┐ ┌────────┐
│ 작업 │ │재시도 │
│ 수행 │ │(50ms) │
└───┬───┘ └────────┘
│
▼
┌───────┐
│ 락해제 │
└───────┘
매개변수:
lockKey: 락 키 (예: "stock:lock:1")value: 락의 식별자 (UUID-랜덤값)duration: 락이 자동으로 해제될 시간 (100ms)DB_Processing_Time (10ms) +
Network_Latency (3ms) +
Buffer_Time (87ms) = 100ms
Active_Threads (24) ×
Avg_Processing_Time (15ms) ×
Safety_Factor (2.0) = 1440ms ≈ 4초
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│StockService │ --> │ LockService │ --> │LockRedis │
│ │ │ │ │Repository │
└─────────────┘ └──────────────┘ └─────────────┘
┌─────────┐ 락 요청 ┌─────────┐
│Thread 1 │ ────────> │ Redis │
└─────────┘ └─────────┘
│ │
│ 실패 시 Sleep │
│<─────────────────── │
│ │
│ 재시도 (50ms 후) │
│────────────────────>│
┌─────────┐ 락 요청 ┌─────────┐
│Thread 1 │ ────────> │ Redis │
└─────────┘ └─────────┘
│ │
│ 구독 & 대기 │
│<─────────────────── │
│ │
│ 락 해제 알림 │
│<═══════════════════ │
│ │
│ 즉시 재시도 │
│────────────────────>│
| 구분 | MySQL Lock | Redis Lock |
|---|---|---|
| 인프라 | 별도 불필요 | Redis 필요 |
| 분산 환경 | 제한적 | 완벽 지원 |
| 성능 | DB 부하 증가 | 메모리 기반 고속 |
| 확장성 | 단일 DB 한계 | 수평 확장 용이 |
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Domain A │────>│ RestTemplate │────>│ Domain B │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
└──────────── Event System ───────────────┘
MSA 전환 고려
확장성
성능
백오프 전략이란 재시도 간격을 점점 늘려가는 방법
Redis나 네트워크 부하를 줄여 시스템 안정성 향상