ํด๋ผ์ฐ๋ ํ๊ฒฝ ๊ธฐ๋ฐ ๊ณ ๊ฐ์ฉ์ฑ ํฐ์ผํ
ํ๋ซํผ
๋๊ท๋ชจ ๋์ ์ ์ ํ๊ฒฝ์์ ์์ ์ ์ธ ์ข์ ์ ์ , ์๋งค, ๊ฒฐ์ ๊ธฐ๋ฅ์ ์ ๊ณต.
- ์ ๋ ๋ ๋๋ถ๊ธฐ ๋๋น 306์ต ์ ์ฆ๊ฐ
- ๋ํ ๊ณต์ฐ๋ฟ ์๋๋ผ ์ค์ํ ๊ณต์ฐ ์์ฅ๋ ํ๋ ์ค
- ์ฐ๋ฆฌ์ํ ํฐ์ผํ ํ๋ซํผ ์ง์ถ ์์
- ์ค์ํ ๊ณต์ฐ๊ณผ์ ์์ ๊ฐ์น ์คํ ๊ฐ๋ฅ
- ๊ณต์ฐ ์๋ฆผ ์์ฝ ์, ๊ณต์ ์๋งค ์ฌ์ดํธ ์ฃผ์๋ฅผ ๋ฉ์ผ๋ก ๋ฐ์ก
- ์ฌ์ฉ์๊ฐ ์์ ํ๊ฒ ๋ฐ๋ก ์ ์ โ ํผ์ฑ ์ํ ์ต์ํ
- ๊ธฐ์กด ์ฌ์ดํธ: ์์ฌ์ ํ์ธ ๋ถํธ
- ๋ณธ ํ๋ซํผ: ์์ธ ํ์ด์ง UI์์ ์ฆ์ ํ์ธ ๊ฐ๋ฅ
- ๊ธฐ์กด: ๊ฒฐ์ ๋จ๊ณ์์ ์ด์ ์ข ๋ฐ์ โ ๋ค์ ์ข์ ์ ํ ํ์
- ๊ฐ์ : ์ข์ ์ ํ ์ ์ฆ์ ์ด์ ์ข ์ฌ๋ถ ํ์ธ ๊ฐ๋ฅ
- ์ธ๊ธฐ ํฐ์ผํ ํ๊ฒฝ์์ ํ ์ข์์ ๋ค์ ์ฌ์ฉ์๊ฐ ๋์์ ์์ฒญ โ ๋์์ฑ ์ด์ ๋ฐ์
- ํด๊ฒฐ์ฑ : Redis ๋ถ์ฐ๋ฝ(Redisson) ์ ์ฉ
// Redis Lock์ผ๋ก ์ข์ ์ด์ ์ข ๊ด๋ฆฌ
public boolean tryLockSeat(Long seatId) {
RLock lock = redissonClient.getLock(SEAT_LOCK_PREFIX + seatId);
String seatKey = SEAT_STATE_PREFIX + seatId;
try {
if (lock.tryLock(1, 10, TimeUnit.SECONDS)) {
String seatStatus = redisTemplate.opsForValue().get(seatKey);
if (!"RESERVED".equals(seatStatus)) {
// Redis์ ์์ ์ ์ ์ํ ์ ์ฅ (TTL: 5๋ถ)
redisTemplate.opsForValue().set(seatKey, "RESERVED", 5, TimeUnit.MINUTES);
return true;
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return false;
}
- ๋์ ์์ฒญ ํ ์คํธ (100์ข์ ร 100๋ช ์์ฒญ)
- ๊ฒฐ๊ณผ: ๋ชจ๋ ์ข์์ด ๋จ ํ ๋ช ๋ง ์ ์ ์ฑ๊ณต
-
ํ์ฌ Redis Lock TTL = 5๋ถ
-
๋ฌธ์ ์ํฉ:
-
์ฌ์ฉ์๊ฐ ์ ์ ์ฑ๊ณต ํ ๊ฒฐ์ ์ ์ ์ค๋ฅ๋ก ์ดํ โ ์ ๋ น๋ฝ(ghost lock) ๋ฐ์
-
ํด๋น ์ข์์ 5๋ถ๊ฐ ์ ์ ๋ถ๊ฐ โ ๋งค์ถ ์์ค ์ํ
-
โก ๋์ ๋ฐฉ์ ํ์
-
์ฅ์ ๊ฐ์ง ์ ๋ฝ ๊ฐ์ ํด์ ๋ก์ง
-
๊ฒฐ์ ํ๋ฆ๊ณผ ์ ์ ์ํ๋ฅผ ์ค์๊ฐ ๋๊ธฐํ
-
์ผ์ ์ฃผ๊ธฐ ์ ๊ฒ(batch)์ผ๋ก ์ ๋ น๋ฝ ๋ณต๊ตฌ