WCF 事务范围不会回滚
本文关键字:事务 范围 WCF | 更新日期: 2023-09-27 18:31:59
我使用了这个指导:http://www.c-sharpcorner.com/uploadfile/shivprasadk/wcf-faq-part-5-transactions/为什么不回滚??我不明白!
我有一个服务和客户端应用程序,我不知道这段代码有什么问题。完美地完成这一行并将其保存在我的数据库中后,
proxy.AddEmployee("Stav", "20");
下一行抛出异常,我没有向 Age 参数发送数字,但事务不会回滚第一行,因此信息:Stav,20 仍然存在于我的数据库中!
proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception)")
编辑 1:我添加了添加员工实现。
客户:
static void Main(string[] args)
{
ServiceReference1.IJob proxy = new ServiceReference1.JobClient();
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
try
{
proxy.AddEmployee("Stav", "20");
proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception) ");//stop the running and show the Exception but keep the stav,20 in DB
ts.Complete();
}
catch
{
ts.Dispose();
}
}
}
服务:
[ServiceContract]
public interface IJob
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void AddEmployee(string Name, string Age);
}
public class JobImplement:IJob
{
[OperationBehavior(TransactionScopeRequired = true)]
public void AddEmployee(string Name, string Age)
{
string strConnection = @"Data Source=.'SQLEXPRESS;AttachDbFilename=C:'Users'stavalfi'Desktop'WCF2'ConsoleApplication4'WCF_DB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
SqlConnection objConnection = new SqlConnection(strConnection);
objConnection.Open();
SqlCommand objCommand = new SqlCommand("INSERT INTO Employee (Name,Age) " + "VALUES ('" + Name + "' ,'" + Age + "')", objConnection);
objCommand.ExecuteNonQuery();
objConnection.Close();
}
}
static void Main(string[] args)
{
WSHttpBinding Basic = new WSHttpBinding();
Basic.TransactionFlow = true;
ServiceHost host = new ServiceHost(typeof(JobImplement), new Uri("http://localhost:8080"));
//
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
//
host.AddServiceEndpoint(typeof(IJob), new BasicHttpBinding(), "Request123");
host.Open();
//
Console.WriteLine("opened");
Console.ReadLine();
//
host.Close();
}
看起来您的代码中可能存在拼写错误:
static void Main(string[] args)
{
...
host.AddServiceEndpoint(typeof(IJob), new BasicHttpBinding(), "Request123");
...
}
您正在添加类型为 BasicHttpBinding 的终结点 - 不支持事务的绑定协议。
我想你实际上是想这样做的:
static void Main(string[] args)
{
WSHttpBinding Basic = new WSHttpBinding();
Basic.TransactionFlow = true;
...
host.AddServiceEndpoint(typeof(IJob), Basic, "Request123");
...
}
这将为您提供一个WSHttpBinding 端点 - 一个支持事务的绑定协议。
您应该实现自己的回滚函数。这是一个基本的方法。在服务类接口中添加[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
属性。然后添加以下代码:
private SqlCommand Command { get; set; }
[OperationContract]
public void BeginTransaction()
{
this.Command = new SqlCommand();
string strConnection = @"Data Source=.'SQLEXPRESS;AttachDbFilename=C:'Users'stavalfi'Desktop'WCF2'ConsoleApplication4'WCF_DB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
SqlConnection objConnection = new SqlConnection(strConnection);
objConnection.Open();
this.Command.Connection = objConnection;
}
[OperationContract]
public void RollBackTransaction()
{
this.Command.Transaction.Rollback();
}
[OperationContract]
public void CommitTransaction()
{
this.Command.Transaction.Commit();
}
[OperationContract]
public void CloseConnection()
{
this.Command.Connection.Close();
this.Command = null;
}
[OperationBehavior(TransactionScopeRequired = true)]
public void AddEmployee(string Name, string Age)
{
this.Command.CommandText = "INSERT INTO Employee (Name,Age) " + "VALUES ('" + Name + "' ,'" + Age + "')";
this.Command.ExecuteNonQuery();
}
然后,您可以在客户端代码中访问它,如下所示:
try
{
proxy.BeginTransaction();
proxy.AddEmployee("Stav", "20");
proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception)");
proxy.CommitTransaction();
}
catch
{
proxy.RollBackTransaction();
}
finally
{
proxy.CloseConnection();
}
希望这有帮助。