NServiceBus中需要部分回滚

NServiceBus中需要部分回滚,nservicebus,transactionscope,Nservicebus,Transactionscope,我有一个奇怪的情况。我有一个NServiceBus(v3)处理程序,处理对业务实体的更新。当该实体处于特定状态时,只能更改该实体的一部分(用于帮助调试的引用字段),而放弃其余更新,然后抛出错误 由于NSB处理程序在其自己的事务作用域中运行,因此引发的异常会阻止记录引用字段更新 我原以为我可以强制一个子TransactionScope,但这似乎只是锁定了数据库,并导致NServiceBus出现超时异常,特别是: 类型异常 'NServiceBus.Unicast.Transport.Transpo

我有一个奇怪的情况。我有一个NServiceBus(v3)处理程序,处理对业务实体的更新。当该实体处于特定状态时,只能更改该实体的一部分(用于帮助调试的引用字段),而放弃其余更新,然后抛出错误

由于NSB处理程序在其自己的事务作用域中运行,因此引发的异常会阻止记录引用字段更新

我原以为我可以强制一个子
TransactionScope
,但这似乎只是锁定了数据库,并导致NServiceBus出现超时异常,特别是:

类型异常 'NServiceBus.Unicast.Transport.TransportMessageHandlingFailedException' 被扔了原始异常:超时已过期。超时时间 在操作完成之前已过,或者服务器未运行 回应

示例代码:

public class UpdateEntityHandler : HandlerBase, IHandleMessages<UpdateEntityMessage>
{
    public IEntityService EntityService { get; set; }

    public ILogService LogService { get; set; }

    public void Handle(UpdateEntityMessage message)
    {
        // get the entity
        var entity = this.EntityService.GetEntity(message.Id);

        // log the message (DTC coordinated)
        this.LogService.Log(message);

        // set the reference no
        entity.ReferenceNo = message.ReferenceNo;

        // if some odd condition then we need to exit
        if (entity.TypeId == (int)EntityType.ForceError)
        {
            // force this into it's own TransactionScope
            using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
            {
                // update need to be saved and not rolled back
                this.EntityService.Update(entity);
                scope.Complete();
            }

            // force the error to prevent 
            throw new ApplicationException("Error was forced");
        }

        // Set values
        entity.StatusId = (int)EntityStatus.Updated;
        entity.Balance = this.EntityService.SetBalance(entity, message);

        // update normally
        this.EntityService.Update(entity);
    }
公共类UpdateEntityHandler:HandlerBase,IHandleMessages
{
公共IEntityService EntityService{get;set;}
公共ILogService日志服务{get;set;}
公共无效句柄(UpdateEntityMessage消息)
{
//获取实体
var entity=this.EntityService.GetEntity(message.Id);
//记录信息(DTC协调)
this.LogService.Log(消息);
//设置参考编号
entity.ReferenceNo=message.ReferenceNo;
//如果出现一些奇怪的情况,那么我们需要退出
if(entity.TypeId==(int)EntityType.ForceError)
{
//将此强制输入到它自己的TransactionScope中
使用(var scope=newtransactionscope(TransactionScopeOption.Suppress))
{
//更新需要保存,而不是回滚
this.EntityService.Update(实体);
scope.Complete();
}
//强制错误以防止
抛出新的ApplicationException(“错误被强制”);
}
//设定值
entity.StatusId=(int)EntityStatus.Updated;
entity.Balance=this.EntityService.SetBalance(实体,消息);
//正常更新
this.EntityService.Update(实体);
}

我需要把这个条件当作一个例外(因为其他原因),但是我需要一些不更新的数据库更新。这是可能的吗?< /p> < p>如果您想在另一个事务中记录消息,那么我会考虑做一个.sEndoLoad()。发送到另一个仅执行日志记录的处理程序,或使用审核功能将消息副本转发到另一个端点并在那里执行日志记录。这将确保您的日志记录始终成功,并且实体可以自由回滚


更新:另一种可能是使用自定义故障处理程序来执行所需的日志记录。

Does SendLocal()需要任何进一步的配置,还是只在配置为AsA_Server的程序集中工作?此外,我假设日志消息也不会回滚?不需要进一步的配置。它将发送到端点队列,该队列是本地的,不需要分布式事务。我还没有测试是否发生异常rs审核功能失败。我想不会,但我不想给出错误的答案。发送的消息也会被回滚。@UdiDahan这是我的担心。我想我需要考虑另一种解决方法。我的建议是不要使用异常。