NServiceBus中需要部分回滚

时间:2014-01-07 12:17:30

标签: nservicebus transactionscope

我有一个奇怪的场景。我有一个NServiceBus(v3)处理程序,它处理业务实体的更新。当该实体处于某种状态时,只能更改该实体的一部分(参考字段以帮助调试),而更新的其余部分将被丢弃,然后抛出错误。

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

我以为我可以强制一个孩子TransactionScope,但这似乎只是锁定数据库并导致NServiceBus中的超时异常,具体来说:

  

类型异常   'NServiceBus.Unicast.Transport.TransportMessageHandlingFailedException'   被扔了。 OriginalException:超时已过期。超时期限   在完成操作之前经过或服务器没有经过   响应。

示例代码:

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);
    }

我需要将此条件视为异常(由于其他原因),但我需要一些不回滚的数据库更新。这可能吗?

1 个答案:

答案 0 :(得分:0)

如果你想在另一个事务中记录消息,那么我会考虑对另一个只进行日志记录的处理程序执行.SendLocal(),或者使用审计功能将消息的副本转发到另一个端点,在那里做日志。这将确保您的日志记录始终成功,并且实体可以自由回滚。

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