在 WebAPI 中为异步操作中的 TransactionScope 使用自定义 IHttpActionInvoker
Using Custom IHttpActionInvoker in WebAPI for TransactionScope in Async actions
我想为每个异步控制器操作应用 TransactionScope。我不想在每个动作中都这样做,而是想在一个中心位置进行,以便它适用于所有动作。我尝试创建一个继承自 ApiControllerActionInvoker
的自定义 IHttpActionInvoker
public class ControllerActionTransactionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
Task<HttpResponseMessage> result;
result = base.InvokeActionAsync(actionContext, cancellationToken);
scope.Complete();
return result;
}
}
}
然后在 Web Api 的启动 class 中用新创建的
替换默认的 IHttpActionInvoker
config.Services.Replace(typeof(IHttpActionInvoker), new ControllerActionTransactionInvoker());
现在,我可以调用控制器操作并获得结果,但我手动引发了一系列 Db 操作的异常,并且所需的事务处理不起作用。所以在数据库中完成了部分工作。
在 Azure api 应用程序中托管 api 后,它根本不起作用。它说找不到控制器操作。
如何解决?
您的 scope
正在完成并在控制器操作完成执行之前被处置,因为您没有等待响应。试试这样:
public class ControllerActionTransactionInvoker : ApiControllerActionInvoker
{
public override async Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
HttpResponseMessage result = await base.InvokeActionAsync(actionContext, cancellationToken);
scope.Complete();
return result;
}
}
}
虽然这可能很有效,但您可能还想考虑在 Web API 堆栈的更高层执行此操作 - 也许在处理程序中 - 因为您可能会错过其他事务 activity 例如处理程序、过滤器等。取决于您想要进出范围的内容。
我想为每个异步控制器操作应用 TransactionScope。我不想在每个动作中都这样做,而是想在一个中心位置进行,以便它适用于所有动作。我尝试创建一个继承自 ApiControllerActionInvoker
的自定义 IHttpActionInvokerpublic class ControllerActionTransactionInvoker : ApiControllerActionInvoker
{
public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
Task<HttpResponseMessage> result;
result = base.InvokeActionAsync(actionContext, cancellationToken);
scope.Complete();
return result;
}
}
}
然后在 Web Api 的启动 class 中用新创建的
替换默认的 IHttpActionInvokerconfig.Services.Replace(typeof(IHttpActionInvoker), new ControllerActionTransactionInvoker());
现在,我可以调用控制器操作并获得结果,但我手动引发了一系列 Db 操作的异常,并且所需的事务处理不起作用。所以在数据库中完成了部分工作。 在 Azure api 应用程序中托管 api 后,它根本不起作用。它说找不到控制器操作。
如何解决?
您的 scope
正在完成并在控制器操作完成执行之前被处置,因为您没有等待响应。试试这样:
public class ControllerActionTransactionInvoker : ApiControllerActionInvoker
{
public override async Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
HttpResponseMessage result = await base.InvokeActionAsync(actionContext, cancellationToken);
scope.Complete();
return result;
}
}
}
虽然这可能很有效,但您可能还想考虑在 Web API 堆栈的更高层执行此操作 - 也许在处理程序中 - 因为您可能会错过其他事务 activity 例如处理程序、过滤器等。取决于您想要进出范围的内容。