我很好奇MassTransit消费者在实际检索msg之前是否可以Peek()MSMQ队列。
步骤/过程是什么:
1)Msg发送到队列
2)消费者得到它并且必须进行数据库更新 - 大约需要5秒
3)如果第一轮更新,消费者必须进行第二轮更新。
我的问题是,如何处理如果第一个数据库更新失败,消息留在队列中(即网络问题而无法访问数据库)的情况。
目前,只要它从队列中读取消息,就会将其删除,然后如果数据库更新失败,它就会消失。
此外,我如何处理电源故障 - 我的意思是如果消费者通过“工作”的一半,无论是(db update或其他什么)和电源芯片等,我该如何重新运行队列中的msg进程?让我们说这个工作(无论如何我当前的实例)正在推动一个新的行到一个表。我的意思是我可以编写代码来首先检查行是否存在,然后是否删除消息,如果没有则运行任务,但是如何才能让它重新运行整个过程呢? / p>
我已经读过我可以Peek()
队列,然后运行任务,然后读取队列消息真实并删除它,但我不能为我的生活弄清楚是否适用于公共交通......有点失落......
另外我知道Masstransit有.RetryLater
但是我在这个过程中使用它吗?是Initially
- > When
- > Then
- >传奇中的.RetryLater
任何指针都会被指定
最基本的问候 罗宾
修改
PS:我正在使用传奇......
Define(() =>
{
RemoveWhen(saga => saga.CurrentState == Completed);
Initially(
When(NewAC)
.Then((saga, message) => saga.ProcessPSM(message),
InCaseOf<Exception>()
.TransitionTo(Problem)
)
.Then((saga, message) => saga.PostProcessPSM())
.Complete()
);
During(Problem,
When(Waiting)
// NOTE: THIS DOES NOT WORK!!!!
.RetryLater()
);
});
RetryLater抛出错误: “现有的传奇故事不能接受这条消息”
我不确定我还能如何访问'RetryLater'。
答案 0 :(得分:7)
MassTransit抽象出底层队列的概念。所以Peek不是解决方案, 但它确实有其他重试消息的方法。如果您只对处理错误和故障条件感兴趣,则以下机制就足够了。
默认情况下,如果使用者抛出异常,则会重试N次消息:
如果您想要一种更细粒度的错误处理方法,您可以实现Context Consumer,捕获可恢复或瞬态异常并手动调用RetryLater。根据我的理解,这可以完成多少次没有限制。
public class RetryConsumer : Consumes<AwesomeMessage>.Context
{
public void Consume(IConsumeContext<AwesomeMessage> message)
{
try
{
Console.WriteLine("This is Attempt " + message.RetryCount);
// Do Something
}
catch (SomeTransientException e)
{
message.RetryLater();
}
}
}