|
|
@@ -150,7 +150,8 @@ public class ReportCollectService {
|
|
|
log.warn("异步采集草稿不存在 draftId={}", draftId);
|
|
|
return;
|
|
|
}
|
|
|
- if (STATUS_COMPLETED.equals(draft.getParseStatus())) {
|
|
|
+ if (STATUS_COMPLETED.equals(draft.getParseStatus())
|
|
|
+ || draft.getConfirmedReportId() != null) {
|
|
|
return;
|
|
|
}
|
|
|
String pdfPath = null;
|
|
|
@@ -262,12 +263,11 @@ public class ReportCollectService {
|
|
|
healthReportDraftService.updateParseMethod(draftId, method);
|
|
|
healthReportDraftService.updatePayload(draftId, objectMapper.writeValueAsString(payload));
|
|
|
|
|
|
- // 幂等守卫:解析期间若草稿已被确认入库或已完成(并发/外部触发),跳过本次入库
|
|
|
- HealthReportDraft fresh = healthReportDraftService.getDraftById(draftId);
|
|
|
- if (fresh != null && (fresh.getConfirmedReportId() != null
|
|
|
- || STATUS_COMPLETED.equals(fresh.getParseStatus()))) {
|
|
|
- log.warn("草稿解析期间已被处理,跳过重复入库 draftId={}, confirmedReportId={}, parseStatus={}",
|
|
|
- draftId, fresh.getConfirmedReportId(), fresh.getParseStatus());
|
|
|
+ // 幂等守卫:原子抢占插入槽位(collecting -> inserting 且 confirmed_report_id 为空)。
|
|
|
+ // 并发重跑任务(定时重试驱动器/外部触发)解析完成后到达此处时,只有先到者能抢到槽位,
|
|
|
+ // 后到者因 parse_status 已变为 inserting 或 confirmed_report_id 非空而失败,避免重复入库。
|
|
|
+ if (!healthReportDraftService.tryClaimInsertSlot(draftId)) {
|
|
|
+ log.warn("草稿插入槽位已被抢占或已入库,跳过重复入库 draftId={}", draftId);
|
|
|
return;
|
|
|
}
|
|
|
|