NServiceBus 传奇设计问题
NServiceBus saga design issue
我在使用 NServiceBus saga 时遇到 "optimistic concurrency violation" 异常。
我的 saga 涵盖了一个相对简单的流程:当任何消息到达时,它会发出很少的外部请求,并在一段时间后收集回复。
您可以在下面找到我的故事示例。
NServiceBus 为这种流产生 "optimistic concurrency violation" 异常是正常行为吗?
我是否应该考虑以某种方式重新设计传奇?
class MySaga: SqlSaga<SagaData>, ...
{
CorrelationPropertyName => nameof(SagaData.UserId);
public Task Handle(StartSagaMessage message, IMessageHandlerContext context)
{
// save a new item id
Data.Items.Add(message.ItemId);
// make an external request for the item title
context.Send<GetItemTitle>(message.ItemId);
// make an external request for the item description
context.Send<GetItemDescription>(message.ItemId);
// gather results after one hour
RequestTimeout<RequestTimeout>(TimeSpan.FromHours(1));
}
// this method sometimes raises "optimistic concurrency violation" exception
public Task Handle(GetItemTitleResponse message, IMessageHandlerContext context)
{
Data.ItemTitles[message.ItemId] = message.ItemTitle;
}
// this method sometimes raises "optimistic concurrency violation" exception
public Task Handle(GetItemDescriptionResponse message, IMessageHandlerContext context)
{
Data.ItemDescriptions[message.ItemId] = message.ItemDescription;
}
public Task Handle(RequestTimeout state, IMessageHandlerContext context)
{
context.Send<ProcessItems>(Data.Items, Data.ItemTitles, Data.ItemDescriptions);
MarkAsComplete();
}
}
我正在使用:
- NServiceBus 6.4.2
- NServiceBus.RabbitMQ
- NServiceBus.Persistence.Sql
Is it a normal behavior for NServiceBus to produce the "optimistic concurrency violation" exception for such flow?
当然可以。如果与同一 Saga 实例相关的多个消息到达并尝试同时更新 saga 实例数据,持久性将检测到它并抛出此异常。您不必担心,因为 recoverability feature(NServiceBus 重试)会处理它。如果您禁用了可恢复性,则可能需要打开。
Should I consider redesigning the saga somehow?
如果您的传奇负载非常高,那么您可以查看 this blog post 中列出的选项。
我在使用 NServiceBus saga 时遇到 "optimistic concurrency violation" 异常。
我的 saga 涵盖了一个相对简单的流程:当任何消息到达时,它会发出很少的外部请求,并在一段时间后收集回复。
您可以在下面找到我的故事示例。
NServiceBus 为这种流产生 "optimistic concurrency violation" 异常是正常行为吗?
我是否应该考虑以某种方式重新设计传奇?
class MySaga: SqlSaga<SagaData>, ...
{
CorrelationPropertyName => nameof(SagaData.UserId);
public Task Handle(StartSagaMessage message, IMessageHandlerContext context)
{
// save a new item id
Data.Items.Add(message.ItemId);
// make an external request for the item title
context.Send<GetItemTitle>(message.ItemId);
// make an external request for the item description
context.Send<GetItemDescription>(message.ItemId);
// gather results after one hour
RequestTimeout<RequestTimeout>(TimeSpan.FromHours(1));
}
// this method sometimes raises "optimistic concurrency violation" exception
public Task Handle(GetItemTitleResponse message, IMessageHandlerContext context)
{
Data.ItemTitles[message.ItemId] = message.ItemTitle;
}
// this method sometimes raises "optimistic concurrency violation" exception
public Task Handle(GetItemDescriptionResponse message, IMessageHandlerContext context)
{
Data.ItemDescriptions[message.ItemId] = message.ItemDescription;
}
public Task Handle(RequestTimeout state, IMessageHandlerContext context)
{
context.Send<ProcessItems>(Data.Items, Data.ItemTitles, Data.ItemDescriptions);
MarkAsComplete();
}
}
我正在使用:
- NServiceBus 6.4.2
- NServiceBus.RabbitMQ
- NServiceBus.Persistence.Sql
Is it a normal behavior for NServiceBus to produce the "optimistic concurrency violation" exception for such flow?
当然可以。如果与同一 Saga 实例相关的多个消息到达并尝试同时更新 saga 实例数据,持久性将检测到它并抛出此异常。您不必担心,因为 recoverability feature(NServiceBus 重试)会处理它。如果您禁用了可恢复性,则可能需要打开。
Should I consider redesigning the saga somehow?
如果您的传奇负载非常高,那么您可以查看 this blog post 中列出的选项。