You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
 ---&gt; 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.&lt;.ctor&gt;b__13_2(BehaviorContext`1 context, State state) in /_/src/MassTransit/SagaStateMachine/MassTransitStateMachine.cs:line 52
   at MassTransit.SagaStateMachine.StateMachineState`1.MassTransit.State&lt;TSaga&gt;.Raise[T](BehaviorContext`2 context) in /_/src/MassTransit/SagaStateMachine/SagaStateMachine/StateMachineState.cs:line 162
   at MassTransit.MassTransitStateMachine`1.MassTransit.StateMachine&lt;TInstance&gt;.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:30:58