2012-09-18 25 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); 
    } 
} 

另外请注意,这些属性是唯一一个这样做实现这一目标的方式 - 你也可以做如果需要,在配置文件中。通过配置文件可以更轻松地将这些设置一次性应用于多个服务。