在我的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块中,新上下文的打开失败,并显示有关事务处于操作无效状态的错误。
答案 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();
}