如何防止 NServiceBus 回滚事务或事务的一部分?

How to prevent NServiceBus from rolling back the transaction or parts of it?

我们有一个处理程序在收到消息时按预期执行。该过程中有几个步骤,每个连续的步骤都会创建自己的新上下文,如下所示。

public void Handle(SomeMessage message)
{
  ...
  try
  {
    ...
    using(DataContext context = new DataContext()) { ... }
    ...
    using(DataContext context = new DataContext()) { ... }
    ...
  }
  catch (Exception exception)
  { 
    ...
    using(DataContext context = new DataContext()) { ... }
    ...
  }
}

但是,有时会抛出并捕获异常。当前事务被回滚(因为它不是由我明确实现的,所以我假设,但不完全确定,它是由 NServiceBus 本身完成的,因为写入数据库的所有结果都消失了,包括 catch语句)。

目前,我正在通过在发生可怕的事情时写入文件来解决这个问题,但我也希望将其存储在数据库中。

所以,最终,我想防止最后一个操作,即 catch 语句中的操作被回滚。可以这样做吗?如果可以,怎么做?

我真的很想知道更大的问题,你想达到什么目的?为什么要在发生错误时向数据库中记录一些内容?如果它与技术相关,消息应该开始出现在错误队列中,您应该修复错误并让 NServiceBus 重试消息。当它与业务相关时,您应该有一个备用路径来处理特定的业务需求。例如,您的某个特定商品缺货,那么最好给买家发电子邮件等待他们的商品或告诉他们可以退款。并通知销售人员有人购买了缺货的商品,或类似的商品。

NServiceBus 会回滚所有事务,但这是一个 TransactionScope 相关的问题。开始一个新的 TransactionScope 并告诉它是一个新的根事务。

using(TransactionScope scope1 = new TransactionScope()) 
//Default is Required 
{ 
     using(TransactionScope scope2 = new 
      TransactionScope(TransactionScopeOption.Required)) 
     {
     ...
     } 

     using(TransactionScope scope3 = new TransactionScope(TransactionScopeOption.RequiresNew)) 
     {
     ...
     } 

     using(TransactionScope scope4 = new 
        TransactionScope(TransactionScopeOption.Suppress)) 
    {
     ...
    } 
}

scope3 事务本身就是一个事务。如果你愿意,把它放在你的捕获范围内。

This article 说明了一切。 但同样,我宁愿获得更多关于您实际想要实现的目标的信息。也许阅读 this article.