• Spring StateMachine 使用@WithStateMachine 遇到的transition报错,状态无法回滚的问题


    背景

    在使用spring statemachine的框架 的时候,为了方便配置所有action行为
    spring 提供了 @WithStateMachine 注解,具体使用如下

    @WithStateMachine(id = "test1")
    public class MyTransation {
        @OnTransition(source = "S_INIT", target = "S1")
        public boolean toState1(@EventHeaders Map headers,
                      ExtendedState extendedState,
                      StateMachine stateMachine,
                      Message message,
                      Exception e) {
            System.out.println("toState1 #######################################, 当前状态" +  stateMachine.getState());
            throw new RuntimeException("asfa");
        }
    
    
        @OnTransition(source = "S1", target = "S2")
        public void toState2(StateContext stateContext) {
            System.out.println("trial   toState2 ####################################### " + stateContext.getTarget().getId());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在使用注解的时候,这里特意去抛一个异常,场景是很常见的,在不知道哪个步骤里面,可能动作【action】会涉及到数据库存储、外部调用,往往会出现异常的情况。

    其实站在使用者的角度来看,起始此时状态是不能流转成功的【案例中S_INIT -> S1理应失败】

    然而,实际测试的结果有点出乎意料:

    即使被注解过的方法【handler】在其内部抛出异常【或者执行异常】,并不会影响状态的正常流转。

    言外之意,不能把@OnTransition注解的方法当作正常的action来使用.

    分析原因

    原因是出现在onTransaction这个注解,spring state machine是如何处理的。
    核心类:

    1. org.springframework.statemachine.processor.StateMachineHandlerCallHelper
      在这里插入图片描述
      如图,该场景是通过获取在spring启动过程中扫描得到的方法列表所组成的handlerList,并筛选出符合当前转换的方法执行。我们主要看第二个步骤
      在这里插入图片描述
      可以看到,即使当前handler处理报错,是不会网上抛异常的。
      那么问题来了,在我们执行action的时候,一旦报错,那么就不会进行状态的转换。那么以上的问题到底是怎么理解。用户配置的@WithStateMachine 具体是在哪个生命周期中执行的。

    为了一探究竟,我们看哪个地方调用了call

    在这里插入图片描述

    可以看到notifyTransition ,这个含义就是通知的意思,其语义就是一种监听行为,监听transition转换过程中发送的状态变化时候执行的操作。
    那么继续查看调用栈,其实是在触发doAction的过程之后才执行的异步通知流程。此时,doAction
    在这里插入图片描述
    报错,才不会执行状态流转,而监听状态流转是不会控制状态流转的。

    所以用户在使用spring stateMachine中的注解@WithStateMachine 的时候要切记,这个方法只是一种监听器行为,而不会控制状态的流转。

    结论:
    不能把@OnTransition注解的方法当作正常的action来使用.,官网也处理这一句话
    在这里插入图片描述

    该注解的行为于监听状态机的事件是一致的。所以,切记把它当作监听器使用,即使报错也不影响主流程的状态流转。
    千万不要因为方便而随意使用。

  • 相关阅读:
    90%测试工程师都会的用例设计步骤,麻麻再也不用担心我写用例了
    (※)力扣刷题-字符串-实现 strStr()(KMP算法)
    PKCS#11:密码设备与应用程序的密码学接口
    【老生谈算法】matlab在材料力学中的应用
    宇凡微Y51T合封射频芯片,集成433M芯片和MCU
    Springboot+Rabbitmq消费者注解详解、改序列化方式
    经常被问到的react-router实现原理详解
    [非线性控制理论]8_三种鲁棒控制器的比较
    【1++的C++进阶】之异常
    【微信小程序系列:四】前端利用wx.setStorageSync缓存设置有效时间
  • 原文地址:https://blog.csdn.net/u012491646/article/details/126875104