如何为web服务设置Rebus事务上下文



假设我有一个web/SOAP服务,我如何为Rebus(消息总线)设置和拆除适当的事务上下文?当Rebus调用消息处理程序时,这不是问题,因为Rebus将在调用处理程序之前设置事务上下文-但是相反的情况是,web服务处理程序需要通过Rebus发送/发布消息?

我对如何实现HTTP模块或类似的东西不感兴趣-只有围绕Rebus的基础知识:准备Rebus发送消息需要什么?

web服务代码在与应用程序数据库通信时有自己的事务正在进行。我需要能够设置Rebus时设置数据库事务和提交/回滚Rebus时做相同的数据库。

我在独立命令行程序中也有类似的问题,需要与数据库交互并发送Rebus消息。

Rebus将自动在自己的"环境事务上下文中"登记发送和发布操作,该操作通过静态(*)AmbientTransactionContext.Current属性访问。

如果你想的话,你可以自己实现ITransactionContext,但是Rebus自带DefaultTransactionContext

你可以这样使用:

using(var context = new DefaultTransactionContext())
{
    AmbientTransactionContext.Current = context;
    // send and publish things in here
    // complete the transaction
    await context.Complete();
}

可以很容易地放在例如OWIN中间件或类似的东西中。


(*)属性是静态的,但是底层的值被绑定到当前的执行上下文(通过使用CallContext.LogicalGet/SetData),这意味着您可以将其视为线程绑定的,它具有一个很好的属性,即它按照预期流向延续。

在Rebus 2.0.2中,可以通过使用Action<ITransactionContext>Func<ITransactionContext>调用AmbientTransactionContext.SetAccessors(...)来定制用于获取/设置上下文的访问器,例如:

AmbientTransactionContext.SetAccessors(
    context => {
        if (HttpContext.Current == null) {
            throw new InvalidOperationException("Can't set the transaction context when there is no HTTP context");
        }
        HttpContext.Current.Items["current-rbs-context"] = context
    },
    () => HttpContext.Current?.Items["current-rbs-context"] as ITransactionContext
);

在这种情况下,它使它的工作方式,即使在使用老式的HTTP模块;)

相关内容

  • 没有找到相关文章

最新更新