fix(ops): 补齐状态转换审计闭环,回滚场景也留痕到 bus_log
问题:ops_order_event 在主事务内写,事务 rollback 则整段记录消失;
若状态机转换抛异常或并发冲突被拒,线上只有控制台日志而无数据库审计,
运维难以追溯"是谁、在什么时候、尝试做了什么转换、为什么失败"。
设计:中央事件发布 + TransactionalEventListener 双阶段落盘
1. OrderTransitionAttemptedEvent(新)
覆盖 transition 成功、失败、FOR UPDATE 被拒三种情况,携带 orderId、
fromStatus、targetStatus、errorCode、errorMessage、causeSummary 等。
2. OrderLifecycleManagerImpl
- transition 成功分支:publishAttempt(success=true)
- transition 失败分支(context.hasError):publishAttempt(success=false,
errorCode=INVALID_TRANSITION, cause=摘要)
- dispatch FOR UPDATE 命中分支:publishAttempt(success=false,
errorCode=ASSIGNEE_HAS_ACTIVE_ORDER)
publishAttempt 内部 try/catch,审计失败不影响主流程。
3. OrderTransitionAuditListener(新)
- @TransactionalEventListener(AFTER_COMMIT, fallbackExecution=true)
主事务已提交,按事件本身的 success 写 bus_log;INFO 级。
- @TransactionalEventListener(AFTER_ROLLBACK) + @Transactional(REQUIRES_NEW)
主事务已回滚,事件里声称的 success 强制视为失败;独立事务写 bus_log
避免因主事务回滚而日志同样丢失。
- errorCode、fromStatus、targetStatus、reason、cause 全部落 payload。
- 冲突(ASSIGNEE_HAS_ACTIVE_ORDER)→ WARN;其他失败 → ERROR。
4. LogType 新增 TRANSITION_FAILED、DISPATCH_REJECTED。
5. EventLogRecorder 接口补 recordSync(实现类已有同名方法)。
运维查询:按 eventDomain='dispatch' + eventLevel IN ('WARN','ERROR')
即可一眼看出所有"尝试但未成功"的状态转换。errorCode 留在 payload JSON 内,
未升级为一等字段(后续如需聚合统计再迁移)。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>