我有一个奇怪的场景。我有一个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);
}
我需要将此条件视为异常(由于其他原因),但我需要一些不回滚的数据库更新。这可能吗?
答案 0 :(得分:0)
如果你想在另一个事务中记录消息,那么我会考虑对另一个只进行日志记录的处理程序执行.SendLocal(),或者使用审计功能将消息的副本转发到另一个端点,在那里做日志。这将确保您的日志记录始终成功,并且实体可以自由回滚。
更新:另一种可能性是使用自定义错误处理程序来执行所需的日志记录。