具有异步wcf服务的TransactionScope

时间:2017-03-15 16:34:10

标签: c# wcf transactionscope

我无法让transactionScope回滚,因为我遗漏了一些东西,或者我误解了transactionScope的目的。

我有以下方法调用两个wcf服务:

    public async Task<IHttpActionResult> Put(IEnumerable<string> values)
    {
        using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
        {
            Task task1 = service1.UpdateAsync(values);

            Task task2 = service2.UpdateAsync(values);

            await Task.WhenAll(task1 , task2);

            scope.Complete();
        }

        return Ok();
    }

每个服务操作都具有以下属性:

 [OperationContract]
 [TransactionFlow(TransactionFlowOption.Allowed)]
 void Update(IEnumerable<string> values);

实际服务(两者相同)

public void Update(IEnumerable<string> values)
{
    foreach (string value in values)
    {
        db1Access.Update(value);
    }
}

SqlAccess(这是我们正在使用的或者自己的库,基本上你的面包和黄油IDbCommand背后的东西):

BaseSqlAccess sqlAccess = factory.CreateSqlAccess("stp_update");
sqlAccess.AddParameter("values", values);

sqlAccess.ExecuteNonQuery();

合同中的绑定具有以下属性:

<wsHttpBinding>
    <binding name="WSHttpCommonBinding" transactionFlow="true">
    </binding>
</wsHttpBinding>

实现服务端点的API配置:

<bindings>
  <wsHttpBinding>
    <binding name="CommonBindingConfiguration" transactionFlow="true" maxReceivedMessageSize="2000000"/>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:56084/service2.svc" binding="wsHttpBinding" bindingConfiguration="CommonBindingConfiguration" contract="IService1" name="IService1EndPoint"/>
  <endpoint address="http://localhost:56084/service2.svc" binding="wsHttpBinding" bindingConfiguration="CommonBindingConfiguration" contract="IService2" name="IService2EndPoint"/>
</client>

如果我在Task.WhenAll它会开始回滚之后抛出一个错误,我的印象是,我也尝试在service2中抛出错误但是service1仍然存在并且没有回滚。

我在这里缺少什么?

有几点需要注意:

  • DataAccess正在执行Procs
  • 每项服务都连接到两个单独的数据库

1 个答案:

答案 0 :(得分:1)

我认为问题在于您没有将TransactionScopeRequired的WCF服务的实现归因于

[OperationBehavior(TransactionScopeRequired = true)]
public void Update(IEnumerable<string> values)
{
    foreach (string value in values)
    {
        db1Access.Update(value);
    }
}

有关此herehere的更多信息。