我已经在我的代码库中定义了如下SM,其中OperationState Enum描述了StateMachine的状态,并且相同的属性是hibernate Entity [OpInfo.java]的一部分。
基本上我有以下两个问题:
1.根据我的要求,每当有状态变化时,我需要将操作状态持久化到OpInfo表中。目前,我已经为每个状态配置了入口操作,即updateOperationState(),但这看起来很幼稚。我希望必须有一些接口/由StateMachine TPL提供的功能,它将以更干净的方式进行持久化,或者应该有某种方式来定义公共条目操作对于每个国家。
2.在高并发期间,我观察到的是,StateMachine错过了对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;
}
字符串
1条答案
按热度按时间syqv5f0l1#
使用可以利用
StateMachineListener
接口,并在stateEntered
或transitionEnded
阶段实现回调,以便将状态机的当前状态保存到数据库中查看更多Spring文档