MassTransit状态机NotAcceptedStateMachineException异常求助
MassTransit状态机异常:Final状态下无法处理DataReport事件
状态机正常场景运行正常,但当DataRunningFault消息的消费者抛出异常时,状态机会切换至ClearDataState,等待DataCalculated或DataReport消息执行数据删除操作(异常可能在这两个消息发送后触发)。功能可用,但会抛出MassTransit.NotAcceptedStateMachineException,提示Final状态无法处理DataReport事件。已尝试调整事件位置、修改InstanceState等方式,均未解决。
相关代码
DataState 类
public class DataState : SagaStateMachineInstance { public Guid CorrelationId { get; set; } public int CurrentState { get; set; } public int ReadyEventStatus { get; set; } public Guid RequestId { get; set; } }
DataStateMachine 类
public class DataStateMachine : MassTransitStateMachine<DataState> { public Event<DataRequested>? DatakRequested { get; } public Event<Fault<DataRequested>>? DataRequestedFault { get; } public Event<DataRunning>? DataRunning { get; } public Event<Fault<DataRunning>>? DataRunningFault { get; } public Event<DataCalculated> DataCalculated { get; } public Event<Fault<DataCalculated>>? DataCalculatedFault { get; } public Event<DataReport> DataReport { get; } public Event<Fault<DataReport>>? DataReportFault { get; } public MassTransit.Event? Finished { get; } public State? ClearDataState { get; } public DataStateMachine() { InstanceState(x => x.CurrentState); Event(() => DataRequested, x => x.CorrelateById(context => context.Message.RequestId)); Event(() => DataRequestFault, x => x.CorrelateById(context => context.Message.Message.RequestId)); Event(() => DataRunning, x => x.CorrelateById(context => context.Message.RequestId)); Event(() => DataRunningFault, x => x.CorrelateById(context => context.Message.Message.RequestId)); Event(() => DataCalculated, x => x.CorrelateById(context => context.Message.RequestId)); Event(() => DataCalculatedFault, x => x.CorrelateById(context => context.Message.Message.RequestId)); Event(() => DataReport, x => x.CorrelateById(context => context.Message.RequestId)); Event(() => DataReportFault, x => x.CorrelateById(context => context.Message.Message.RequestId)); Initially( When(DataRequested) .Then(x => { x.Saga.Entities = x.Message.Entities; x.Saga.BatchDate = x.Message.BatchDate; x.Saga.RequestId = x.Message.RequestId; }), When(DataRequestFault) .Publish(x => Fault(x.Saga)) .TransitionTo(ClearDataState), When(DataRunning), When(DataRunningFault) .Publish(x => Fault(x.Saga)) .TransitionTo(ClearDataState), When(DataCalculated), When(DataCalculatedFault) .Publish(x => Fault(x.Saga)) .Finalize(), When(DataReport), When(DataReportFault) .Publish(x => Fault(x.Saga)) .Finalize() ); During(ClearDataState, When(DataCalculated) .Publish(x => new DeleteCalculateData() { RequestId = x.Message.RequestId }) .Finalize(), When(DataReport) .Publish(x => new DeleteCalculateData() { RequestId = x.Message.RequestId }) .Finalize() ); CompositeEvent(() => Finished, x => x.ReadyEventStatus, CompositeEventOptions.IncludeInitial, DataRequested, DataRunning, DataCalculated ); During(Initial, When(Finished) .Publish(context => { return new DataFinished() { RequestId = context.Saga.RequestId }; }) .Finalize() ); SetCompletedWhenFinalized(); } private DataFinishedFault Fault(RunDataState runDataState) { return new DataFinishedFault() { RequestId = runDataState.RequestId }; } }
异常信息
MassTransit: Error: R-FAULT sb://testbusfortestingstandard.servicebus.windows.net/messaging-run-data-state bca30000-4395-e04f-ceb8-08dbe1bde727 SharedContracts.Messages.ReportCalculateFinished Messaging.StateMachines.DataState(00:00:00.8759128) MassTransit.NotAcceptedStateMachineException: Messaging.StateMachines.DataState(63331cb1-6165-4260-9577-66be080a3d9e) Saga exception on receipt of SharedContracts.Messages.DataReport: Not accepted in state Final ---> MassTransit.UnhandledEventException: The DataReport event is not handled during the Final state for the DataStateMachine state machine at MassTransit.MassTransitStateMachine`1.DefaultUnhandledEventCallback(UnhandledEventContext`1 context) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 219 at MassTransit.MassTransitStateMachine`1.UnhandledEvent(BehaviorContext`1 context, State state) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 1260 at MassTransit.MassTransitStateMachine`1.<.ctor>b__13_2(BehaviorContext`1 context, State state) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 52 at MassTransit.SagaStateMachine.StateMachineState`1.MassTransit.State<TSaga>.Raise[T](BehaviorContext`2 context) in /_/src/MassTransit/SagaStateMachine/SagaStateMachine/StateMachineState.cs:line 162 at MassTransit.MassTransitStateMachine`1.MassTransit.StateMachine<TInstance>.RaiseEvent[T](BehaviorContext`2 context) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 132 at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 66 --- End of inner exception stack trace --- at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 81 at MassTransit.Middleware.StateMachineSagaMessageFilter`2.Send(SagaConsumeContext`2 context, IPipe`1 next) in /_/src/MassTransit/Middleware/StateMachineSagaMessageFilter.cs:line 104 at MassTransit.Middleware.SendSagaPipe`2.Send(SagaRepositoryContext`2 context) in /_/src/MassTransit/Middleware/SendSagaPipe.cs:line 43 at MassTransit.Middleware.SendSagaPipe`2.Send(SagaRepositoryContext`2 context) in /_/src/MassTransit/Middleware/SendSagaPipe.cs:line 67 at MassTransit.Saga.InMemorySagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Sagas/Saga/InMemoryRepository/InMemorySagaRepositoryContextFactory.cs:line 40 at MassTransit.DependencyInjection.DependencyInjectionSagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, Func`3 send) in /_/src/MassTransit/DependencyInjection/DependencyInjection/DependencyInjectionSagaRepositoryContextFactory.cs:line 101 at MassTransit.DependencyInjection.DependencyInjectionSagaRepositoryContextFactory`1.Send[T](ConsumeContext`1 context, Func`3 send) in /_/src/MassTransit/DependencyInjection/DependencyInjection/DependencyInjectionSagaRepositoryContextFactory.cs:line 110 at MassTransit.Middleware.CorrelatedSagaFilter`2.Send(ConsumeContext`1 context, IPipe`1 next) in /_/src/MassTransit/Middleware/CorrelatedSagaFilter.cs:line 45
问题原因与解决方案
原因
当DataRunningFault触发后,状态机进入ClearDataState,此时如果DataCalculated和DataReport两个消息都被发送,第一个消息会触发状态机进入Final状态,第二个消息到达时,Final状态没有定义对该事件的处理逻辑,因此抛出异常。
解决方案
在状态机构造函数中为Final状态添加对DataCalculated和DataReport事件的忽略处理,避免抛出异常:
// 在SetCompletedWhenFinalized()之前添加 During(Final, When(DataCalculated) .Ignore(), When(DataReport) .Ignore() );
如果需要记录日志,也可以扩展处理逻辑:
During(Final, When(DataCalculated) .Then(context => { context.GetLogger<DataStateMachine>().LogInformation("DataCalculated received in Final state, ignored"); }) .Ignore(), When(DataReport) .Then(context => { context.GetLogger<DataStateMachine>().LogInformation("DataReport received in Final state, ignored"); }) .Ignore() );
额外优化点
- 检查
DataRunningFault触发后,是否可能同时发送DataCalculated和DataReport消息,若可以避免,从源头减少重复消息发送也能解决问题。 - 确保
SetCompletedWhenFinalized()配置正确,Final状态下Saga实例会被标记为完成,部分存储会自动清理实例,但仍需处理延迟到达的消息。
内容的提问来源于stack exchange,提问作者Katarina
相关产品推荐
相关产品推荐

