首页 > 编程知识 正文

spring事务实现原理,进程由就绪状态变为运行状态的条件是

时间:2023-05-04 16:11:09 阅读:137942 作者:3416

一方面,概念Spring Statemachine是APP开发者在spring APP中使用状态机概念的框架,从设计层面进行分析:状态机的目的是解决复杂的状态管理过程,保证程序的单一原则和开关原则; 业务分析:状态机需要初始化状态,加载所有现有状态、事件、转换和操作,并驱动以下状态,解决了业务逻辑和状态管理之间的强耦合:

二、Spring Statemachine旨在提供以下功能: 易于使用的平面一级状态机适合简单的用例。 状态机结构简化了复杂的状态配置。 状态机区域提供了更复杂的状态设置。 使用触发器、切换、保护和操作。 类型安全配置适配器。 构建模式常见用例配方基于Zookeeper的分布式状态机事件侦听器,可以在spring APP应用程序的上下文之外轻松实例化。 UML Eclipse Papyrus建模。 将机器配置保存到永久存储器。 Spring IOC集成将bean与状态机相关联。 状态机非常强大,总是保证一致的行为,所以调试相对容易。 这是因为操作规则在机器启动时是固定的。 这意味着APP应用程序可能存在于有限数量的状态中,并且某些预定义的触发器可以将APP应用程序从一个状态迁移到下一个状态。 这样的触发器可以基于事件或计时器。

在APP外定义高级逻辑,并依赖状态机来管理状态更简单。 可以通过发送事件、接收更改或简单地请求当前状态来与状态机进行交互。

三、状态机应用场景使用前引入spring-statemachine依赖: dependencygroupidorg.spring framework.state machine/groupidartifactidspring-state maching artifactidversion2.1.2. release/version/dependency定义驱动状态: publicenumorderstatus ///无备注}驱动事件定义: public enum ChangeEvent { PAYED,//支付DELIVERY,//发货RECEIVED,//收到COMMENT; //评价} 以上定义的状态和事件驱动迁移: @ configuration @ enablestatemachine @ SLF4jpublicclassorderstatemachineconfigextendstatemachineconfigure rceprivateorderstatelistenerimplorderstatelistener; @ resourceprivatepayedactionpayedaction; @ resourceprivatedeliveryactiondeliveryaction; @ resourceprivatereceivedactionreceivedaction; @ resourceprivatecommentedactioncommentedaction; @ resourceprivateuncommentedactionuncommentedaction; @ resourceprivatedeliveryguarddeliveryguard; @ resourceprivatepayedguardpayedguard; @ resourceprivatereceivedguardreceivedguard; @ resourceprivatecommentguardcommentguard; @ overridepublicvoidconfigure (statemachinestateconfigurerorderstatus,changeeventstates (throws exception ) States.with sth initial (order status.wait _ payment ) /设定用于条件判断的状态。 /绑定所有状态. States(enumset.allof ) orderStatus.class; } @Override

public void configure(StateMachineTransitionConfigurer<OrderStatus, ChangeEvent> transitions) throws Exception { // 1、withExternal 是当source和target不同时的写法 // 2、withInternal 当source和target相同时的串联写法,比如付款失败时,付款前及付款后都是待付款状态 // 3、withChoice 当执行一个动作,可能导致多种结果时,可以选择使用choice+guard来跳转 transitions // 通过PAYED 实现由 WAIT_PAYMENT => WAIT_DELIVER 状态转移 .withExternal() .source(OrderStatus.WAIT_PAYMENT) .target(OrderStatus.WAIT_DELIVER) .event(ChangeEvent.PAYED) .guard(payedGuard) .action(payedAction) .and() // 通过DELIVERY 实现由 WAIT_DELIVER => WAIT_RECEIVE 状态转移 .withExternal() .source(OrderStatus.WAIT_DELIVER) .target(OrderStatus.WAIT_RECEIVE) .event(ChangeEvent.DELIVERY) .guard(deliveryGuard) .action(deliveryAction) .and() // 通过RECEIVED 实现由 WAIT_RECEIVE => FINISH 状态转移 .withExternal() .source(OrderStatus.WAIT_RECEIVE) .target(OrderStatus.FINISH) .event(ChangeEvent.RECEIVED) .guard(receivedGuard) .action(receivedAction) .and() // Choice的状态选择, // commentGuard的结果为true则执行first // commentGuard的结果为true则执行then .withChoice() .source(OrderStatus.FINISH) .first(OrderStatus.COMMENTED, commentGuard, commentedAction) .then(OrderStatus.UNCOMMENTED, commentGuard, uncommentedAction) .last(OrderStatus.WAIT_COMMENT); } @Override public void configure(StateMachineConfigurationConfigurer<OrderStatus, ChangeEvent> config) throws Exception { // 状态转移监听事件 config.withConfiguration().listener(orderStateListener); }} 相关方法调用执行前后解释: withExternal 是当source和target不同时的写法,比如付款成功后状态发生的变化。withInternal 当source和target相同时的串联写法,比如付款失败后都是待付款状态。withExternal的source和target用于执行前后状态、event为触发的事件、guard判断是否执行action。同时满足source、target、event、guard的条件后执行最后的action。withChoice 当执行一个动作,可能导致多种结果时,可以选择使用choice+guard来跳转withChoice根据guard的判断结果执行first/then的逻辑。withChoice不需要发送事件来进行触发。 状态转移驱动监听器: @Component@Slf4jpublic class OrderStateListenerImpl extends StateMachineListenerAdapter<OrderStatus, ChangeEvent> { @Override public void stateChanged(State<OrderStatus, ChangeEvent> from, State<OrderStatus, ChangeEvent> to) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("stateChanged"); stringBuilder.append(" from " + (null != from ? from.getId().name() : null)); stringBuilder.append(" to " + (null != to ? to.getId().name() : null)); log.info(stringBuilder.toString()); } @Override public void transition(Transition<OrderStatus, ChangeEvent> transition) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("transition"); stringBuilder.append(" kind " + (null != transition.getKind() ? transition.getKind().name() : null)); stringBuilder.append(" from " + (null != transition.getSource() ? transition.getSource().getId().name() : null)); stringBuilder.append(" to " + (null != transition.getTarget() ? transition.getTarget().getId().name() : null)); stringBuilder.append(" trigger " + (null != transition.getTrigger() ? transition.getTrigger().getEvent().name() : null)); log.info(stringBuilder.toString()); }} 启动服务状态机(初始化所有驱动状态): @SpringBootApplication@Slf4jpublic class FsmApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(FsmApplication.class, args); } @Resource private StateMachine<OrderStatus, ChangeEvent> stateMachine; @Override public void run(String... args) throws Exception { stateMachine.start(); // 测试状态机消息变更 messageTransfer(); stateMachine.stop(); } private void messageTransfer() { OrderInfo orderInfo = new OrderInfo(); orderInfo.setOid(110350339917373440L); orderInfo.setDesc("test order"); Message<ChangeEvent> message = null; log.info("current state {}", stateMachine.getState().getId().name()); // spring message的payload设置为消息事件、header为额外需要带的参数 message = MessageBuilder.withPayload(ChangeEvent.PAYED).setHeader("order", orderInfo).build(); stateMachine.sendEvent(message); log.info("current state {}", stateMachine.getState().getId().name()); message = MessageBuilder.withPayload(ChangeEvent.DELIVERY).setHeader("order", orderInfo).build(); stateMachine.sendEvent(message); log.info("current state {}", stateMachine.getState().getId().name()); message = MessageBuilder.withPayload(ChangeEvent.RECEIVED).setHeader("order", orderInfo).build(); stateMachine.sendEvent(message); log.info("current state {}", stateMachine.getState().getId().name()); }} 四、关于StateMachine使用总结 定义状态机相关状态和事件驱动枚举;状态机使用的所有状态以及状态管理初始化;驱动状态转移事件机制(包含状态转移、事件、动作);为状态机驱动转移动作事件实现指定监听器。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。