事务失败后写入数据库

时间:2015-03-25 15:36:24

标签: transactions nservicebus

在我的NServiceBus消息处理程序中,我有这样的代码:

  try{
    using(ctx = new dbcontext()){
        var recordToActOn = ctx.Records.Find(message.RecordId);

        code here to act on record, causing updates to other tables in ctx.

        recordToActOn.Success = true;
        ctx.SaveChanges()
    }
  }
  catch(Exception ex)
  {
    using(ctx2 = new dbcontext()){
        var recordToActOn = ctx2.Records.Find(message.RecordId);
        recordToActOn.Success = false;
        recordToActOn.Error = ex.Message;
        ctx2.SaveChange();
    }
    throw; //so that NServiceBus can handle the exception and initiate it's retry logic
  }
}

我需要保存到recordToActOn有关其失败原因的详细信息。但是,在该catch块中,新上下文的打开失败,并显示有关事务处于操作无效状态的错误。

1 个答案:

答案 0 :(得分:3)

我最好的猜测是你的处理程序在事务范围内运行(NServiceBus中的默认设置)。一旦发生故障,整个事务将被回滚,因此无法再使用。

您可以使用以下方法关闭此行为:

        TransactionSettings transactionSettings = configuration.Transactions();
        transactionSettings.DoNotWrapHandlersExecutionInATransactionScope();

另一种选择可能是为catch子句使用单独的事务范围。我不确定您是否应该使用 Suppress RequiresNew TransactionScopeOption,但这样的事情可以解决它:

   using(TransactionScope scope2 = new TransactionScope(TransactionScopeOption.Suppress))
   using(ctx2 = new dbcontext())
   {
        var recordToActOn = ctx2.Records.Find(message.RecordId);
        recordToActOn.Success = false;
        recordToActOn.Error = ex.Message;
        ctx2.SaveChange();
    }