Search code examples
c#transactionstransactionscopedistributed-transactions

WCF TransactionScope doesnt RollBack


I have used this guid: http://www.c-sharpcorner.com/uploadfile/shivprasadk/wcf-faq-part-5-transactions/ Why doesnt it rollback?? I dont understand!

I have a service and client Application and I dont have a clue what is the problem with this code. after doing this line perfectly and save it in my DB,

proxy.AddEmployee("Stav", "20");

the next line throw Exception becouse I didnt send a number to the Age parameter, but the Transaction doesnt RollBack the first line so the Information : Stav, 20 still exsist in my DB!

proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception)") 

EDIT 1: I add the AddEmployee implement.

client:

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();
                }
            }
        }

service:

[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();
        }

Solution

  • It looks like you have a possible typo in your code here:

    static void Main(string[] args)         
    {             
        ...
        host.AddServiceEndpoint(typeof(IJob), new BasicHttpBinding(), "Request123");   
        ...
    }
    

    You are adding an endpoint of type BasicHttpBinding - a binding protocol that does not support transactions.

    I am thinking that you actually meant to do this:

    static void Main(string[] args)         
    {             
        WSHttpBinding Basic = new WSHttpBinding();
        Basic.TransactionFlow = true;  
        ...
        host.AddServiceEndpoint(typeof(IJob), Basic, "Request123");   
        ...
    }
    

    That would give you a WSHttpBinding endpoint - a binding protocol that does support transactions.