Files
aiot-platform-cloud/viewsh-module-ops/viewsh-module-ops-biz
lzh ba6f94a279 fix(ops): review 复盘补齐 FOR UPDATE 覆盖面 + 清理注解/日志死角
今日 review 发现 Bug #2 的 FOR UPDATE 防线只装在 dispatch() 上,但同文件另有两条
路径绕过它:

1. P1 — DispatchEngineImpl.autoDispatchNext 调 transition() 派发队列下一单,
   不走 FOR UPDATE。idle 校验和 transition 之间存在竞争窗口,能再次让同 assignee
   挂两条 DISPATCHED。改调 dispatch(),天然继承串行化。
   补测 autoDispatchNext_whenDispatchingFromQueue_shouldGoThroughDispatchNotTransition
   锁定该不变量。

2. P2 — OrderLifecycleManagerImpl.resumeOrder/resumeInterruptedOrder 同样走
   transition(),P0 恢复与并发派发竞争时可能产生两条 DISPATCHED。改为先
   selectById 取 assigneeId,改调 dispatch() 让同一检查生效。

顺手清理 3 个误导:

- DispatchEngineImpl.executePushAndEnqueue 原先忽略内部 dispatch 的返回值,
  并发场景下会输出假的“已推送等待任务”日志误导运维,改为按 result.isSuccess()
  分支打印。
- OrderTransitionAuditListener.writeRollbackAudit 的 @Transactional(REQUIRES_NEW)
  是死注解(由 onAfterRollback 自调用,Spring 代理无法拦截;且 AFTER_ROLLBACK
  本就无事务),移除并更新 Javadoc 说明实际行为。
- OrderQueueServiceEnhanced.triggerQueueRebuildAfterCommit 的自调用绕过
  @Transactional 是设计意图(最终一致即可),补 Javadoc 解释事务边界,
  避免后续误判为 bug。

测试:ops-biz 56 个相关用例全部通过,含新增的 P1 锁定测试。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 14:51:32 +08:00
..