如何将数据库中的状态持久化为Spring状态机中每个状态的条目的一部分?

问题描述 投票:0回答:1

我在我的代码库中定义了如下所示的SM,其中OperationState Enum描述了StateMachine的状态,并且相同的属性是休眠实体[OpInfo.java]之一的一部分

基本上我有以下2个问题:

1.根据我的要求,我需要将操作状态持久化到 每当状态发生变化时 OpInfo 表。目前,我有 配置条目操作,即 updateOperationState() 为每个 但国家这种做法看起来很幼稚。我希望一定有 StateMachine TPL 提供的一些接口/功能将 以更干净的方式进行这种持久化,或者应该有某种方法 为每个状态定义通用的进入操作。

2.在高并发期间,我观察到的是,调用 EntryAction 即 updateOperationState() 被错过 状态机。我想了解同样的根本原因 想知道SM是否有公开的配置 调整这个问题。

    StateMachineBuilder.Builder<OperationState, OperationEvent> builder = StateMachineBuilder.builder();
                        builder.configureStates().withStates()
                                .states(EnumSet.allOf(OperationState.class))
                                .initial(genericOp.getOpState())
                                .state(CREATED, updateOperationState(), null)
                                .state(IDLE, updateOperationState(), null)
                                .state(APPLYING, updateOperationState(), null)
                                .state(APPLIED, updateOperationState(),null);
        
        builder.configureTransitions().withExternal()
                            .source(CREATED).target(APPLYING).event(TRIGGER)
                            .and().withExternal()
                            .source(CREATED).target(IDLE).event(SCHEDULE)
                            .and().withExternal()
                            .source(IDLE).target(APPLYING).event(TRIGGER)
                            .and().withExternal()
                            .source(APPLYING).target(APPLIED).event(SUCCESS)
                            .and().withExternal();
@Bean
private static Action<OperationState, OperationEvent> updateOperationState() {
    return context -> {
        OperationState tgtOpState = context.getStateMachine().getState().getId();
        if (context.getMessage() == null) {
            return;
        }
        opInfoRepository.updateOpState(opId, tgtOpState);
        log.debug("Updating the operation [{}] state to [{}]", opId, tgtOpState);

    };
}

@Entity
@Builder
public class OpInfo {
    @Id
    @ToString.Include
    private String id;
    
    @Enumerated(EnumType.STRING)
    @ToString.Include
    private OperationType operationType;
    
    @Enumerated(EnumType.STRING)
    OperationState operationState =  OperationState.CREATED;
}
java spring spring-data-jpa concurrency spring-statemachine
1个回答
0
投票

用户可以利用

StateMachineListener
接口并在
stateEntered 
transitionEnded
阶段实现回调,将状态机的当前状态保存在数据库中

在 Spring 文档中查看更多这里

© www.soinside.com 2019 - 2024. All rights reserved.