resetStateMachine设初始状态致ID置空,如何在重置时保留或重设状态机ID
状态机重置后保留/恢复ID的可行方案
出现该问题的核心原因是resetStateMachine方法会用传入的StateMachineContext全量覆盖状态机内部属性,传入的上下文没有携带原有ID,因此ID会被默认置为null。
方案1:重置时将原有ID传入上下文(推荐)
该方案从根源上适配状态机的重置逻辑,无额外时序问题,优先推荐使用。
- 操作步骤:
- 重置前先缓存原有状态机的ID
- 构造重置上下文时,将缓存的ID赋值给上下文属性
- 再执行原有重置逻辑
- 示例代码:
// 重置前提前缓存原有ID String originalId = stateMachine.getId(); // 构造重置用的上下文 DefaultStateMachineContext<S, E> resetContext = new DefaultStateMachineContext<>(correctState, null, null, null); // 将原有ID写入上下文,避免被重置逻辑置为null resetContext.setId(originalId); // 执行重置操作 stateMachine.getStateMachineAccessor().doWithAllRegions(access -> access.resetStateMachine(resetContext));
方案2:重置完成后显式设置ID
该方案改动量最小,适合已经写好大量重置逻辑、不想改动原有上下文构造代码的场景。
- 操作步骤:
- 同样在重置操作执行前缓存原有状态机的ID
- 执行完原有重置逻辑后,直接调用状态机的
setId方法恢复缓存的ID
- 示例代码:
// 重置前提前缓存原有ID String originalId = stateMachine.getId(); // 执行原有的重置逻辑(无改动) stateMachine.getStateMachineAccessor().doWithAllRegions(access -> access .resetStateMachine(new DefaultStateMachineContext<>(correctState, null, null, null))); // 重置完成后显式恢复原有ID stateMachine.setId(originalId);
注意事项
- 两种方案都必须在重置操作执行前缓存原有ID,一旦执行完重置流程,原有ID就会被置空,无法再追溯。
- 优先选择方案1,避免异步执行的重置回调逻辑读取到临时的null ID,引发业务异常。
- 多实例状态机的工厂管理场景下,要确保缓存的ID和对应状态机实例一一绑定,避免出现跨实例复用ID的问题。
内容的提问来源于stack exchange,提问作者alegria
相关产品推荐
相关产品推荐

