Spring State机器不接受来自多个用户的同一事件

Mit*_*hun 4 spring state-machine spring-statemachine

我有简单的状态机跟随States,EventsTransitions.

状态: WIP, SUBMITTED, REJECTED, APPROVED

事件: SUBMIT, APPROVE, REJECT

转变:

@Override
public void configure(StateMachineTransitionConfigurer<States,Events> transitions) 
                          throws Exception {
    transitions
        .withExternal()
            .source(States.WIP)
            .target(States.SUBMIT)
            .event(Events.SUBMIT)
            .and()
        .withExternal()
            .source(States.SUBMITTED)
            .target(States.APPROVED)
            .event(Events.APPROVE)
            .and()
        .withExternal()
            .source(States.SUBMITTED)
            .target(States.REJECTED)
            .event(Events.REJECT);;
}
Run Code Online (Sandbox Code Playgroud)
  1. WIP为SUBMIT事件提交
  2. 提交批准APPROVE活动
  3. 提交拒绝REJECT活动

我已将WIP初始状态设置如下:

@Override
public void configure(StateMachineStateConfigurer<States, Events> states) 
            throws Exception {
    states
    .withStates()
        .initial(States.WORK_IN_PROGRESS)
        .states(EnumSet.allOf(States.class));
}
Run Code Online (Sandbox Code Playgroud)

多个用户将与此状态机进行交互.当源和目标状态的组合多次引发相同的事件时,状态机仅接受第一个事件,不接受后续事件.

这是状态机的有效行为吗?如果是,是否需要添加任何额外配置?

Jan*_*hti 6

在这样的场景中使用一个状态机实例只有在代理和批准者都处理一组文档时才有效.当然,它会为现实世界的用例带来问题,因为当审批者将机器恢复到可以提交文档的状态时,代理只能提交新的文档.

因此,您需要为每组提交的文档提供专用实例.这可以通过从配置http://docs.spring.io/spring-statemachine/docs/1.0.0.RELEASE/reference/htmlsingle/#sm-factories中公开工厂或使用构建器http://手动完成.docs.spring.io/spring-statemachine/docs/1.0.0.RELEASE/reference/htmlsingle/#state-machine-via-builder.然后,您需要手动控制与您通话的机器.

您提到,如果您需要重新启动进程持有状态机,那么文档可以在那里等待某人批准哪种类型会产生问题.(你用简单的进程中状态机失去了状态)

我建议采用一种不同的方法来解决这个问题.检查持久化示例http://docs.spring.io/spring-statemachine/docs/1.0.0.RELEASE/reference/htmlsingle/#statemachine-examples-persist这是一个演示,其中"stuff"保存在数据库中单状态机实例用于通过状态机更新数据库.这允许您将您的东西保存在持久存储中并处理状态机中的转换逻辑.

我们目前正试图通过尝试实现更好的持久化模型来使这些使用场景更容易使用,并且可能通过Spring安全性和spring会话引入一些魔法来简化/保护可以在状态机中执行操作的不同角色.所以请继续关注未来版本.