2013-10-26 82 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