我已经通过相关问题进行了很好的拖网并实施了建议,但我仍然遇到.NET TransactionScope的问题。
我从一个方法调用两个WCF服务,即使第二个服务错误(在这种情况下故意)第一个服务不回滚。我已经创建了一个简单的测试应用程序来演示这个问题。
这是调用方法:
private void TryATransaction()
{
ServiceReference1.IService1 service = new ServiceReference1.Service1Client();
ServiceReference2.IService1 service2 = new ServiceReference2.Service1Client();
using (TransactionScope scope = new TransactionScope())
{
service.TestMethod("one");
service2.UpdateSomethingElse("two");
scope.Complete();
}
}
第一项服务看起来像这样(连接是匿名的):
public bool TestMethod(string anything)
{
using (TransactionScope scope = new TransactionScope())
{
// connect to a db
using (SqlConnection connection = new SqlConnection("Data Source=DATASOURCE;Initial Catalog=DATABASE;Integrated Security=SSPI;Transaction Binding=Explicit Unbind;"))
{
connection.Open();
// save something
SqlCommand command1 = new SqlCommand("EXECUTE [DATABASE].[dbo].[uspUpdateCustomer] 3, 'test@test.com', 1, null", connection);
command1.ExecuteNonQuery();
connection.Close();
}
scope.Complete();
}
return true;
}
第二项服务与第一项服务相同,只是它更新了数据库中的其他字段。
1)如果我在没有强制错误的情况下运行它,它会更新所有字段。
2)当我运行此命令并在第二个服务中强制执行错误时,第一个服务的更新将提交到数据库,而第二个服务将被回滚(错误是在ExecuteNonQuery语句之后)。
此示例代码基本上遵循此处的示例: http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
我添加了Explicit Unbind,这在其他相关问题中被推荐。
非常欢迎您的建议 - 如果需要,我很乐意添加更多信息。
额外信息
分布式标识符似乎始终为00000000-0000-0000-0000-000000000000 - 我不知道这是否是线索。
以下是分布式ID和本地ID(按此顺序)的dubug输出
目前的交易是 00000000-0000-0000-0000-000000000000 - f6446876-496d-488c-A21C-1e4c4295d50c:8
目前的交易是 00000000-0000-0000-0000-000000000000 - 7edd5ba3-7f5a-42af-b9ca-37b3862c26a7:2
目前的交易是 00000000-0000-0000-0000-000000000000 - 6fa0e3f7-b655-40ad-8bdd-f0670de79a49:2
通过我的示例应用程序中的aspx页面后面的代码启动事务。
答案 0 :(得分:1)
编辑:抱歉让事情倒退。
很可能是问题是由于将事务与WCF一起使用。
查看有关交易服务的this文章。特别是关于客户/服务模式交易的部分。
基本上你需要:
[TransactionFlow(TransactionFlowOption.Mandatory)]
属性
[OperationBehavior(TransactionScopeRequired = true)]
属性
TransactionFlowBindingElement
添加到服务的BindingContext TransactionScope
,因为您使用的是客户端的TransactionScope。每个成功完成投注的服务方法都会成功投票(当您使用默认的TransactionAutoComplete = true OperationBehavior时)。
如果服务方法因异常而失败,则会投票支持该事务失败。