2013-10-26 50 views
0

我一直在尝试在WCF中实现事务流。当我执行我的客户端代码时,我可以看到事务正在从客户端传播到服务,因为我看到记录被锁定在db中(我在SQL服务器中使用(nolock)来查看事务是否正在发生)。但是我的客户端代码成功完成,但事务回滚,我怀念这里的东西,WCF事务流没有成功提交

以下是代码片段,

服务类

[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.ReadCommitted, TransactionTimeout = "00:00:30")] 
public class TransactionTest : ITransactionTest 
{ 
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = false)] 
public void DoWork(string aliasName) 
{  
    string constr = "Data Source=MyDBServer;User ID=DBUser;password=123;Initial Catalog=MyTestDB;"; 
    using (SqlConnection objcon = new SqlConnection(constr)) 
    { 
     string qry = @"UPDATE Customer SET Alias = '" + aliasName + "' WHERE CustomerID = 10"; 
     SqlCommand cmd = new SqlCommand(qry, objcon); 
     objcon.Open(); 
     cmd.ExecuteNonQuery(); 
    } 
} 

}

Service Contract: 

[ServiceContract(SessionMode = SessionMode.Required)] 
public interface ITransactionTest 
{ 
    [OperationContract, TransactionFlow(TransactionFlowOption.Allowed)]  
void DoWork(string aliasName); 
} 

以下是我的Web.config

<bindings> 
    <wsHttpBinding> 
    <binding name="wsHttpBinding_ITransactionTest" transactionFlow="true"/> 
    </wsHttpBinding> 
</bindings> 

我已经在我的客户端应用程序添加一个服务引用(这是一个控制台应用程序)

class Program 
{ 
    static void Main(string[] args) 
    { 

     //updateCustomeAlias(); 
     try 
     { 
      using (TransactionScope TranScope = new TransactionScope(TransactionScopeOption.RequiresNew)) 
      { 
       var proxy = new TransactionTestClient("WSHttpBinding_ITransactionTest"); 
       proxy.DoWork("XYZ"); 
       TranScope.Complete(); 
      } 
     } 
     catch 
     { 
      //Exception handling. 
     } 
    } 

客户端应用程序配置

<system.serviceModel> 
<bindings> 
    <wsHttpBinding> 
    <binding name="WSHttpBinding_ITransactionTest" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" 
     textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
     maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <reliableSession ordered="true" inactivityTimeout="00:10:00" 
     enabled="false" /> 
     <security mode="Message"> 
     <transport clientCredentialType="Windows" proxyCredentialType="None" 
      realm="" /> 
     <message clientCredentialType="Windows" negotiateServiceCredential="true" 
      algorithmSuite="Default" /> 
     </security> 
    </binding> 
    </wsHttpBinding> 
</bindings> 
<client> 
    <endpoint address="http://localhost:91/TransactionTest.svc" binding="wsHttpBinding" 
    bindingConfiguration="WSHttpBinding_ITransactionTest" contract="TransactionTestService.ITransactionTest"   
    name="WSHttpBinding_ITransactionTest">   
    </endpoint> 
</client> 
</system.serviceModel> 

回答

0

在你[OperationBehavior(TransactionAutoComplete = false)]服务端,这意味着该服务必须明确表决投票或回滚将发生。你有两个选择。在服务方面:

  1. 将行为更改为TransactionAutoComplete = true,除非有异常,否则它将自动投票以提交事务。
  2. 在服务方法TransactionScope(TransactionScopeOption.Required)将获得环境交易范围,您可以拨打Complete()
+0

如果我指定TransactionAutoComplete = False,则客户端事务不会传播到服务。 – user824910

+0

我不明白。你说“交易传播到服务从客户端”和您的代码作为发布集TransactionAutoComplete = False ...什么都没有改变,它没有传播? – ErnieL