Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ public void reconcileStock() {
// 실제 참여자 수 계산 (DB)
long actualParticipantCount = lessonParticipantRepository.countByLessonId(lessonId);

// Redis 재고가 음수라면 producer의 DECR -> INCR rollback 중으로 판단
String redisStockBefore = coreRedisTemplate.opsForValue().get(stockKey);
if (isNegativeRedisStock(lessonId, redisStockBefore)) {
continue;
}

// Lesson 테이블 카운트 보정 및 상태 변경
lessonRepository.updateParticipantCount(lessonId, (int)actualParticipantCount,
com.threestar.trainus.domain.lesson.teacher.entity.LessonStatus.RECRUITMENT_COMPLETED);
Expand All @@ -125,7 +131,6 @@ public void reconcileStock() {
currentStock = 0;

Long waitingRoomSize = coreRedisTemplate.opsForZSet().size(waitingRoomKey);
String redisStockBefore = coreRedisTemplate.opsForValue().get(stockKey);
Long streamSize = mqRedisTemplate.opsForStream().size(LessonApplyStreamConstant.STREAM_KEY);
log.info(
"Reconciliation diagnostics. lessonId={}, dbCount={}, maxParticipants={}, calculatedStock={}, redisStockBefore={}, waitingRoomSize={}, streamSize={}, busyCount={}, lastActive={}",
Expand All @@ -150,6 +155,26 @@ public void reconcileStock() {
log.info("Finished Smart Stock Reconciliation for {} lessons.", processedCount);
}

private boolean isNegativeRedisStock(Long lessonId, String redisStock) {
if (redisStock == null) {
return false;
}

try {
int currentStock = Integer.parseInt(redisStock);
if (currentStock < 0) {
log.info("Redis stock is negative. lessonId={}, stock={}. Postponing reconciliation.", lessonId,
redisStock);
return true;
}
return false;
} catch (NumberFormatException e) {
log.warn("Failed to parse Redis stock. lessonId={}, stock={}. Postponing reconciliation.", lessonId,
redisStock);
return true;
}
}

// 미처리 메세지 확인 메서드 (Core Redis)
private boolean hasWaitingRoomMessages() {
String dirtySetKey = LessonApplyStreamConstant.DIRTY_SET_KEY;
Expand Down
Loading