v1.14.4 重复心跳误取消同步任务修复(issue #43)
v1.14.4
🐛 修复:重复心跳被误判为同步任务取消(issue #43)
现象:大型货源同步在处理到第 10 个商品后可能无故变成 cancelled,但
cancel_requested_at 为空,也没有管理员取消审计。该问题在 MariaDB/MySQL 的 changed-rows
语义下可稳定触发。
根因:同步 Job 在每 10 件商品边界会连续写入相同阶段与进度。若两次心跳发生在同一秒,
第二次 UPDATE 没有实际改变字段,数据库会返回 affected rows 0。旧状态机把 0 直接当成
status != running,随后错误进入取消终态。
修复:
- 继续使用
WHERE status = running的条件更新,保留取消、超时与迟到 worker 之间的并发保护; - affected rows 为
0时重新读取任务状态:仍为running即视为心跳成功; - 只有状态为
cancelling时才完成取消,其他终态仍会阻止 worker 继续执行; - 新增 MariaDB changed-rows 语义回归测试,并覆盖第 10 件后的重复心跳与完整任务成功。
测试
- 心跳专项回归:2 passed,4 assertions;
- 同步任务测试:23 passed,99 assertions;
- 全量
php artisan test:437 passed,1461 assertions; - Laravel Pint 与
git diff --check通过。
升级说明
- 本版本不包含数据库迁移;
- 升级后必须执行
php artisan queue:restart(或重启 Supervisor/systemd worker),让常驻 worker
加载 v1.14.4 的心跳状态机; - 已被误标为
cancelled的历史任务不会自动恢复,可在升级并重启 worker 后重新发起同步。