Wednesday, August 5, 2015

Wcf Transactions

Wcf provides transaction so operations(wcf methods) those are part of a single work unit can be called in a transaction. Operations could be from same or different wcf services.

If any one method out of all methods called in one transaction fails & thrown exception then all other method's operations also rolled back.
Three options are available of transaction flow:
  • Allowed: Marked service method can be called with in transaction or without transaction
  • NotAllowed: Marked service method can't be called in transaction
  • Mandatory: Marked service method must be called in transaction only

Steps to make Wcf service transaction enabled:
  • Create binding tag with attribute transactionFlow is true
    <bindings>
      <wsHttpBinding>
        <binding name ="TransBind" transactionFlow="true"></binding>
      </wsHttpBinding>
    </bindings>
  • Assign binding name to bindingConfiguration attribute of endpoint
    <services>
      <service name="WcfTranService1.Service1" behaviorConfiguration="serviceBehavior">
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
        <endpoint address="" binding="wsHttpBinding" contract ="WcfTranService1.IService1" bindingConfiguration="TransBind"></endpoint>
      </service>
    </services>
  • Mark method in interface with TransactionFlowOption.allowed in TransactionFlow 
        [OperationContract]      
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void SetData(int value);
  • Mark method in service concrete class with TransactionScopeRequired=true in operation behavior
        [OperationBehavior(TransactionScopeRequired=true)]
        public void SetData(int value)
        {
            //return string.Format("You entered: {0}", value);           
            try
            {
                SqlConnection con = new SqlConnection("Initial Catalog= testdb; Data Source= GEN-LAP-00011\\SQLEXPRESS; Integrated Security=SSPI;");
                SqlCommand com = new SqlCommand("insert into tb_city (Name, IsActive) Values(Mumbai service" + value + "',1)", con);
                con.Open();
                com.ExecuteNonQuery();
                con.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
  • Call all methods of a single work unit in one transaction. Methods could be from same or different wcf services
  • Call Complete() method of transaction object if no error
  • Call Dispose() method of transaction in case of error

    TransactionScope
     - System.Transactions
        protected void Page_Load(object sender, EventArgs e)
        {
            using (TransactionScope tr = new TransactionScope(TransactionScopeOption.RequiresNew))
            {
                try
                {
                    ServiceReference1.Service1Client _client1 = new ServiceReference1.Service1Client();
                    ServiceReference2.Service1Client _client2 = new ServiceReference2.Service1Client();
                    _client1.SetData(1);
                    _client2.SetData(2);
                    tr.Complete();
                }
                catch(Exception ex)
                {
                    tr.Dispose();
                }
            }
        }

No comments:

Post a Comment

CI/CD - Safe DB Changes/Migrations

Safe DB Migrations means updating your database schema without breaking the running application and without downtime . In real systems (A...