具有异步 wcf 服务的 TransactionScope
TransactionScope with async wcf service
我无法让 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
- 每个服务都连接到两个独立的数据库
我无法让 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
- 每个服务都连接到两个独立的数据库