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

Kon*_*ten 1 c# entity-framework msmq transactions 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()) { ... }
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

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

目前,我正在通过写一个文件来解决它,当一些可怕的事情发生但我也喜欢将它存储在数据库中.

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

Den*_*elt 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)) 
    {
     ...
    } 
}
Run Code Online (Sandbox Code Playgroud)

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

这篇文章解释了这一切.但同样,我想更多地了解你实际想要实现的目标.也许请阅读本文.