You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring State Machine多初始状态与并发执行支持技术问询

Spring State Machine 集成疑问解答

背景

我们近期已将Spring State Machine集成至工作流,具体使用方式为:从SQS队列接收事件,通过状态机处理;完成状态转换后将事件推回SQS队列持久化,每个事件对应初始化一次状态机并执行转换。

疑问

  • 是否支持从多个初始状态启动,执行至推送事件到SQS队列后暂停,即支持部分执行,而非必须按顺序走完所有阶段?
  • 当前状态机似乎只能单事件处理,能否通过每次触发事件时创建新实例实现多事件并发处理?

状态机配置代码

状态与初始状态配置

public void configure(StateMachineStateConfigurer<RedactionStates, RedactionEvents> states)
    throws Exception {
states.withStates()
        .initial(RedactionStates.S1) // default initial state
        .state(RedactionStates.S2)
        .state(RedactionStates.S3)
        .state(RedactionStates.S4)
        .end(RedactionStates.S5);
}

转换配置

public void configure(
    StateMachineTransitionConfigurer<RedactionStates, RedactionEvents> transitions)
    throws Exception {
transitions
        .withInternal()
        .source(RedactionStates.S1)
        .event(RedactionEvents.E1)
        .and()
        .withExternal()
        .source(RedactionStates.S1)
        .target(RedactionStates.S2)
        .event(RedactionEvents.E2)
       }

解答

1. 多初始状态与部分执行支持

Spring State Machine完全支持这两个需求:

  • 多初始状态配置:在状态配置中,可以通过多次调用.initial()方法指定多个初始状态,例如:
    states.withStates()
          .initial(RedactionStates.S1)
          .initial(RedactionStates.S2)
          // 其他状态配置...
    
    也可以通过传入状态集合的方式批量指定。
  • 部分执行/暂停:你的场景本身就适合实现“暂停”逻辑——每次处理事件时,从SQS消息中读取当前事件对应的状态,初始化状态机到该状态(而非默认初始状态),处理完当前转换后推回SQS,随后销毁状态机实例。下次接收该事件时,重复此流程即可继续执行。
    重置状态机到指定状态的核心代码示例:
    // 从SQS消息中获取当前状态,比如currentState
    StateMachine<RedactionStates, RedactionEvents> stateMachine = stateMachineFactory.getStateMachine();
    stateMachine.getStateMachineAccessor().doWithAllRegions(sma -> {
        sma.resetState(StateMachineState.of(currentState));
    });
    // 触发对应事件
    stateMachine.sendEvent(eventFromSQS);
    

2. 多事件并发处理实现

完全可以通过为每个事件创建独立状态机实例实现多事件并发处理:
Spring State Machine实例是轻量级的,且每个实例的状态相互隔离。你可以通过StateMachineFactory为每个待处理事件创建新实例,示例代码如下:

@Autowired
private StateMachineFactory<RedactionStates, RedactionEvents> stateMachineFactory;

// 处理单个事件的逻辑
public void processEvent(RedactionEvents event, RedactionStates currentState) {
    // 创建新的状态机实例
    StateMachine<RedactionStates, RedactionEvents> stateMachine = stateMachineFactory.getStateMachine();
    // 重置到当前事件对应的状态(如果不是默认初始状态)
    stateMachine.getStateMachineAccessor().doWithAllRegions(sma -> {
        sma.resetState(StateMachineState.of(currentState));
    });
    // 触发事件
    stateMachine.sendEvent(event);
    // 处理完成后,状态机实例可被GC回收,无需手动销毁
}

配合多线程的SQS消费者(例如使用线程池处理消息),就能实现多个事件的并行处理,各实例之间不会互相干扰。


内容的提问来源于stack exchange,提问作者Jaspreet Chhabra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:00:36