2012-09-18 81 views
4

我有一個WPF應用程序,並且在按鈕單擊事件中我調用了WCF服務來處理它中的事務。一次交易完成後,我拋出異常。查看事務是否會回滾。但即使我得到錯誤仍然交易完成它不會在數據庫中止。如何處理WCF服務中的事務

UI按鈕事件:

private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    binding = new WSHttpBinding(); 
    endpoint = new EndpointAddress("http://localhost:6144/EmployeeService.svc/EmployeeService"); 

    ChannelFactory<IEmployeeService> cf = new ChannelFactory<IEmployeeService>(binding, endpoint); 
    IEmployeeService obj = cf.CreateChannel(); 

    using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) 
    { 
     try 
     { 
      obj.UpdateProductData(201, 10); 
      throw new Exception("Wrong"); 
      obj.UpdateProductData(202, 15); 
      ts.Complete(); 
     } 
     catch (Exception ex) 
     { 
      ts.Dispose();       
     } 
    } 
} 

在app.config中,我已經給出"transactionFlow="true"

WCF服務:

[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)] 
public bool UpdateProductData(int ProdId, int Amount) 
{ 
    DALClass objDALProd = new DALClass(); 
    return objDALProd.UpdateProductData(ProdId, Amount); 
} 

DALClass:

public bool UpdateProductData(int prodID,int Amount) 
{ 
    try 
    { 
     objComd.Connection = objConn; 
     objConn.Open(); 
     objComd.CommandText = "UpdateEmployeeData"; 
     objComd.CommandType = CommandType.StoredProcedure; 
     objParam = new SqlParameter("@ProductId", prodID); 
     objComd.Parameters.Add(objParam); 
     objParam = new SqlParameter("@Amount", Amount); 
     objComd.Parameters.Add(objParam); 

     objComd.ExecuteNonQuery(); 
     objConn.Close(); 
    } 
    catch(Exception ex) 
    { 
     throw new FaultException("Database Error"); 
    } 
    return true; 
} 

請讓我知道我的錯誤是。事務不會回滾,即使當我提出異常時,第一個事務也不會回滾。

+0

注意:您不需要'try/catch/ts.Dispose()'部分。這就是'use'塊本身的用途。更糟的是,你吞下所有的例外。 –

+0

嘗試TransactionAutoComplete = false ... –

回答

2

您是否在WCF合同上定義了交易流程?

[OperationContract] 
[TransactionFlow(TransactionFlowOption.Mandatory)] 

您是否在客戶端和服務器配置中定義了事務流?

<wsHttpBinding> 
<binding name="transactionalWsatHttpBinding" 
     transactionFlow="true" /> 
</wsHttpBinding> 
+0

下面是爲WCF合同添加的代碼但沒有用...請讓我知道是否有任何其他方式:[OperationBehavior(TransactionScopeRequired = true,TransactionAutoComplete = true)]公共布爾UpdateProductData(int ProdId,int金額){DALClass objDALProd = new DALClass(); return objDALProd.UpdateProductData(ProdId,Amount); } – user1661171

+0

它看起來像你把類的屬性而不是接口 –

1

您的客戶端代碼對我來說看起來很好,但在服務器端,總共需要3個屬性才能使其發揮作用。

服務接口需要[TransactionFlow]的操作。

[ServiceContract] 
public interface IService 
{ 
    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Allowed)] 
    bool UpdateProductData(int ProdId, int Amount); 
} 

服務類需要[ServiceBehavior]對類和[OperationBehavior]的方法:

[ServiceBehavior(TransactionIsolationLevel = IsolationLevel.ReadUncommitted)] 
public class Service : IService 
{ 
    [OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)] 
    public bool UpdateProductData(int ProdId, int Amount) 
    { 
    DALClass objDALProd = new DALClass(); 
    return objDALProd.UpdateProductData(ProdId, Amount); 
    } 
} 

另外請注意,這些屬性是唯一一個這樣做實現這一目標的方式 - 你也可以做如果需要,在配置文件中。通過配置文件可以更輕鬆地將這些設置一次性應用於多個服務。