From b938547e7542203aa25bff3f20b7b6302554fe57 Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Fri, 14 Aug 2026 15:03:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=94=81=E5=AE=9A=E6=97=A5=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E5=90=8E=E5=88=9B=E5=BB=BA=E8=B0=83=E5=BA=A6=E9=A2=86?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/lms/enums/ErrorCodeConstants.java | 1 + .../dal/mysql/dailyplan/DailyPlanMapper.java | 6 +++++ .../DailyPlanScheduleServiceImpl.java | 17 +++++++++++--- .../mapper/dailyplan/DailyPlanMapper.xml | 22 +++++++++++++++++++ sql/mysql/lms_daily_plan.sql | 11 ++++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java b/nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java index cb6d1838..6b8e062b 100644 --- a/nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java +++ b/nl-module-lms/nl-module-lms-api/src/main/java/cn/code/nl/module/lms/enums/ErrorCodeConstants.java @@ -66,4 +66,5 @@ public interface ErrorCodeConstants { ErrorCode DAILY_PLAN_CLAIM_INVALID = new ErrorCode(41, "日计划领取标识无效、已结束或已过期"); ErrorCode DAILY_PLAN_CLAIM_MISMATCH = new ErrorCode(42, "日计划领取信息与进度确认不一致"); ErrorCode DAILY_PLAN_CLAIM_PROGRESS_CONFLICT = new ErrorCode(43, "日计划作业进度已变化,该领取无法确认"); + ErrorCode DAILY_PLAN_CLAIM_CANDIDATE_CHANGED = new ErrorCode(44, "日计划候选状态已变化,请重新获取"); } diff --git a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/dailyplan/DailyPlanMapper.java b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/dailyplan/DailyPlanMapper.java index db1436f9..3091da39 100644 --- a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/dailyplan/DailyPlanMapper.java +++ b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/dailyplan/DailyPlanMapper.java @@ -51,6 +51,12 @@ public interface DailyPlanMapper extends BaseMapperX { */ DailyPlanDO selectDailyPlanById(@Param("dailyPlanId") Long dailyPlanId); + /** + * 锁定并重新校验可调度计划,Claim 必须使用该锁内快照创建。 + */ + DailyPlanDO selectSchedulableForUpdate(@Param("dailyPlanId") Long dailyPlanId, + @Param("strategyType") Integer strategyType); + /** * 根据 ERP 订单号查询日计划。 */ diff --git a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/dailyplan/DailyPlanScheduleServiceImpl.java b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/dailyplan/DailyPlanScheduleServiceImpl.java index fd8272e0..1fc4181a 100644 --- a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/dailyplan/DailyPlanScheduleServiceImpl.java +++ b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/dailyplan/DailyPlanScheduleServiceImpl.java @@ -24,6 +24,7 @@ import java.util.List; import static cn.code.nl.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.code.nl.module.lms.enums.ErrorCodeConstants.DAILY_PLAN_CLAIM_CONFLICT; +import static cn.code.nl.module.lms.enums.ErrorCodeConstants.DAILY_PLAN_CLAIM_CANDIDATE_CHANGED; import static cn.code.nl.module.lms.enums.ErrorCodeConstants.DAILY_PLAN_CLAIM_INVALID; import static cn.code.nl.module.lms.enums.ErrorCodeConstants.DAILY_PLAN_CLAIM_MISMATCH; import static cn.code.nl.module.lms.enums.ErrorCodeConstants.DAILY_PLAN_CLAIM_PROGRESS_CONFLICT; @@ -84,14 +85,16 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService { } if (mode == DailyPlanStrategyModeEnum.SEQUENCE) { DailyPlanDO selected = candidates.get(0); - return claimCandidate(selected, remaining(selected, type), mode.getCode(), type, operator); + DailyPlanDO locked = lockSchedulablePlan(selected.getDailyPlanId(), type); + return claimCandidate(locked, remaining(locked, type), mode.getCode(), type, operator); } int selectedIndex = findCursorIndex(candidates, strategy.getCursorDailyPlanId()); DailyPlanDO selected = candidates.get(selectedIndex); DailyPlanDO next = candidates.get((selectedIndex + 1) % candidates.size()); - int quantity = Math.min(selected.getWeight(), remaining(selected, type)); - DailyPlanScheduleCandidate candidate = claimCandidate(selected, quantity, mode.getCode(), type, operator); + DailyPlanDO locked = lockSchedulablePlan(selected.getDailyPlanId(), type); + int quantity = Math.min(locked.getWeight(), remaining(locked, type)); + DailyPlanScheduleCandidate candidate = claimCandidate(locked, quantity, mode.getCode(), type, operator); int affected = dailyPlanStrategyMapper.updateCursorWithVersion(strategy.getStrategyId(), next.getDailyPlanId(), strategy.getVersion(), normalizedOperator(operator)); if (affected != 1) { @@ -101,6 +104,14 @@ public class DailyPlanScheduleServiceImpl implements DailyPlanScheduleService { return candidate; } + private DailyPlanDO lockSchedulablePlan(Long dailyPlanId, DailyPlanStrategyTypeEnum type) { + DailyPlanDO locked = dailyPlanMapper.selectSchedulableForUpdate(dailyPlanId, type.getCode()); + if (locked == null) { + throw exception(DAILY_PLAN_CLAIM_CANDIDATE_CHANGED); + } + return locked; + } + private int findCursorIndex(List candidates, Long cursorDailyPlanId) { if (cursorDailyPlanId != null) { for (int i = 0; i < candidates.size(); i++) { diff --git a/nl-module-lms/nl-module-lms-server/src/main/resources/mapper/dailyplan/DailyPlanMapper.xml b/nl-module-lms/nl-module-lms-server/src/main/resources/mapper/dailyplan/DailyPlanMapper.xml index 3d79b084..66f042c4 100644 --- a/nl-module-lms/nl-module-lms-server/src/main/resources/mapper/dailyplan/DailyPlanMapper.xml +++ b/nl-module-lms/nl-module-lms-server/src/main/resources/mapper/dailyplan/DailyPlanMapper.xml @@ -51,6 +51,28 @@ ORDER BY plan_date DESC, sort_seq ASC, daily_plan_id DESC + +