如何防止NServiceBus回滚事务或其中的部分内容?

时间:2015-09-27 09:09:49

标签: c# entity-framework transactions msmq nservicebus

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

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本身完成,因为所有结果都写入了DB消失,包括 catch 语句中的那些。)

目前,当发生可怕的事情时,我会通过写入文件来解决它,但我也很乐意将其存储在数据库中。

因此,最终,我想阻止上一次操作( catch 语句中的操作)回滚。一个人可以这样做,如果是这样的话?

1 个答案:

答案 0 :(得分:6)

我真的很想知道更重要的问题,你想要实现什么目标?为什么要在发生错误时将某些内容记录到数据库中?如果它与技术相关,则消息应该开始出现在错误队列中,您应该修复错误并让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