fix:参赛者id逻辑更改

This commit is contained in:
litianxiang
2026-02-04 17:20:22 +08:00
parent f2d43f06f4
commit 1ec42f4ad5
2 changed files with 54 additions and 29 deletions

View File

@@ -158,34 +158,59 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
LocalDateTime now = LocalDateTime.now();
if (existing == null) {
// 由数据库自增分配 contestant_number(请确保数据库列为 AUTO_INCREMENT
Contestant toInsert = Contestant.builder()
.email(request.getEmail())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.gender(request.getGender())
.occupation(request.getOccupation())
.age(request.getAge())
.countryRegionCity(request.getCountryRegionCity())
.phoneNumber(request.getPhoneNumber())
.designTitle(request.getDesignTitle())
.designDescription(request.getDesignDescription())
.pdfPath(request.getPdfPath())
.videoPath(request.getVideoPath())
.videoDuration(request.getVideoDuration())
.videoSize(request.getVideoSize())
.pdfSize(request.getPdfSize())
.createdAt(now)
.updatedAt(now)
.build();
contestantMapper.insert(toInsert);
// 重新查询以获取数据库分配的 contestant_number
Contestant saved = contestantMapper.selectById(toInsert.getId());
Integer assignedNumber = (saved == null) ? null : saved.getContestantNumber();
resp.put("success", true);
resp.put("contestant_number", assignedNumber);
sendSiteMsg(toInsert.getId(), toInsert.getEmail());
return resp;
// 通过行锁 + 重试机制保证 contestant_number 在并发下自增分配
final int maxAttempts = 5;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
try {
// 获取当前最大 contestant_number 并加行锁LIMIT 1 FOR UPDATE
QueryWrapper<Contestant> qMax = new QueryWrapper<>();
qMax.isNotNull("contestant_number");
qMax.orderByDesc("contestant_number");
qMax.last("LIMIT 1 FOR UPDATE");
Contestant last = contestantMapper.selectOne(qMax);
Integer nextNumber = (last == null || last.getContestantNumber() == null) ? 10000 : last.getContestantNumber() + 1;
Contestant toInsert = Contestant.builder()
.email(request.getEmail())
.firstName(request.getFirstName())
.lastName(request.getLastName())
.gender(request.getGender())
.occupation(request.getOccupation())
.age(request.getAge())
.countryRegionCity(request.getCountryRegionCity())
.phoneNumber(request.getPhoneNumber())
.designTitle(request.getDesignTitle())
.designDescription(request.getDesignDescription())
.pdfPath(request.getPdfPath())
.videoPath(request.getVideoPath())
.videoDuration(request.getVideoDuration())
.videoSize(request.getVideoSize())
.pdfSize(request.getPdfSize())
.contestantNumber(nextNumber)
.createdAt(now)
.updatedAt(now)
.build();
contestantMapper.insert(toInsert);
resp.put("success", true);
sendSiteMsg(toInsert.getId(), toInsert.getEmail());
return resp;
} catch (Exception e) {
log.warn("Attempt {} to assign contestant_number failed", attempt, e);
String msg = e.getMessage() == null ? "" : e.getMessage().toLowerCase();
if ((msg.contains("duplicate") || msg.contains("uniq_contestant_number") || msg.contains("contestant_number")) && attempt < maxAttempts) {
try {
Thread.sleep(100L);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
continue;
}
throw e;
}
}
throw new BusinessException("Failed to assign contestant number after retries.");
} else {
// update existing contestant
existing.setFirstName(request.getFirstName());
@@ -205,7 +230,6 @@ public class GlobalAwardServiceImpl implements GlobalAwardService {
existing.setUpdatedAt(now);
contestantMapper.updateById(existing);
resp.put("success", true);
resp.put("contestant_number", existing.getContestantNumber());
return resp;
}
}