2009-11-26 48 views
0

我已经通过相关的问题和实现的建议找到了很好的拖网,但我仍然有一个NET TransactionScope的问题。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, '[email protected]', 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

我添加显式取消绑定,这是在其他相关问题,建议。

您的建议非常受欢迎 - 如果需要,我很乐意添加更多信息。

额外信息

分布式标识似乎是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

一个问题:(可能是愚蠢的):我们期望TransactionScope跨客户端和服务器边界工作,它支持它吗? – 2009-11-26 09:36:26

回答

1

编辑:对不起有东西倒退。

最可能的问题是由于与WCF一起使用事务。

结账this关于交易服务的文章。特别是关于客户/服务模式交易的部分。

基本上你需要:

  • 设置[TransactionFlow(TransactionFlowOption.Mandatory)]属性上的OperationContract的接口方法
  • 设置[OperationBehavior(TransactionScopeRequired = true)]属性就其执行
  • 添加TransactionFlowBindingElement到的BindingContext服务
  • 去除因为您使用的是客户端的TransactionScope,所以您的服务实现中的TransactionScope

成功完成事务投票的每个服务方法(当您使用默认的TransactionAutoComplete = true OperationBehavior时)。

如果服务方法由于异常而失败,它会投票处理失败。

+0

我的问题是相反的 - 我希望内部事务使用我在调用这两个服务的方法中创建的环境事务 - 这样,如果其中任何一个服务失败,整个事件都会回滚。 – Fenton 2009-11-26 09:27:38

+0

是的 - 这些属性似乎是这个关键 - 谢谢你回来调整! – Fenton 2009-11-26 11:08:05

+0

很高兴我能帮忙:-) – 2009-11-26 11:28:20

相关问题