加锁解决不同线程读取前还未保存的问题

This commit is contained in:
litianxiang
2026-03-24 15:49:16 +08:00
parent 2168978f61
commit 9be1a1e307

View File

@@ -219,6 +219,8 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
version = "fast";
params.put("version", "fast");
}
// 4、将请求信息落库,将本次generate的请求信息添加到t_generate表中
saveGenerateImmediately(generate);
// 3.1 确定不同类型的印花分别调哪个接口
if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())) {
switch (generateThroughImageTextDTO.getLevel2Type()) {
@@ -258,8 +260,6 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
.prompt(text).build();
jsonString = JSON.toJSONString(imageProcessRequest);
}
// 4、将请求信息落库,将本次generate的请求信息添加到t_generate表中
saveGenerateImmediately(generate);
Boolean requestResult = pythonService.generateSketchOrPrint(jsonString, port, path,generateThroughImageTextDTO.getUniqueId());
@@ -276,9 +276,31 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
}
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void saveGenerateImmediately(Generate generate) {
save(generate);
// 写入完成后设锁,通知 MQ 消费者可以安全读取
String lockKey = "generate:lock:" + generate.getUniqueId();
redisUtil.addToString(lockKey, "1", 60L);
}
private void waitForSaveLock(String uniqueId) {
String lockKey = "generate:lock:" + uniqueId;
int maxRetries = 30;
int retryIntervalMs = 200;
for (int i = 0; i < maxRetries; i++) {
if (Boolean.TRUE.equals(redisUtil.hasKey(lockKey))) {
log.debug("Save lock acquired for uniqueId: {} after {} retries", uniqueId, i);
return;
}
try {
Thread.sleep(retryIntervalMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.warn("Interrupted while waiting for save lock: {}", uniqueId);
return;
}
}
log.warn("Save lock timeout for uniqueId: {}, proceeding anyway", uniqueId);
}
public GenerateModeEnum getMode(GenerateThroughImageTextDTO generateThroughImageTextDTO) {
@@ -307,6 +329,8 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO();
Generate generate;
try {
// 等待 HTTP 线程写入完成后再查库
waitForSaveLock(taskId);
generate = selectByUniqueId(taskId);
} catch (MybatisPlusException e) {
log.error(e.getMessage());