Transactions provide a
way to perform one or more than one
operations as single unit of work
Transaction characteristics
- Atomic (either all the operations of the transactions succeed or none of them succeed )
- Consistent (outcome is exactly what we expected it to be)
- Isolated (Isolated transactions are "private," meaning that no one else knows about the transaction until it is committed)
- Durable
Name space used : System.Transactions
WCF supports
transaction on following bindings :
1.
WSHttpBinding
2.
NetTcpBinding
3.
NetNamedPipeBinding
4.
WSDualHttpBinding
5.
WSFederationHttpBinding
TransactionFlow Attribute :
It has
three options:
- Allowed: Transaction may be flowed.
- Mandatory: Transaction must be flowed.
- NotAllowed (default): Transaction cannot be flowed
While developing a Service Contract we have to specify the TransactionFlow attribute on each
Operation Contracts that requires a Transaction to be handled
Operation Contracts that requires a Transaction to be handled
[ServiceContract]
public interface ITransectionService
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Displaydata();
}
ServiceBehavior Attribute
The
[ServiceBehavior] attribute has three properties that deal with handling and
managing transactions
TransactionAutoCompleteOnSessionClose: Specifies whether pending
transactions are completed either commited or rollback when the current session closes.
TransactionIsolationLevel: Determines the isolation level(hold
locks on the data) of the transaction.
TransactionTimeout: Specifies the period in which a
transaction has to complete. If the
transaction has not completed before the timeout value has been reached, the
transaction is rolled back.
OperationBehavior
Attribute :
The [OperationBehavior] also has followingof
properties related to transactions.
TransactionAutoComplete:
Specifies that transactions will be auto-completed if no exceptions occur.
TransactionScopeRequired:
Specifies whether the associate method requires a transaction.
[OperationBehavior(TransactionScopeRequired
= true,TransactionAutoComplete=true)]
Enable transaction flow using WCF service config file
<bindings>
<wsHttpBinding>
<binding name="TransactionalBind" transactionFlow="true"/>
</wsHttpBinding>
</bindings>
Example :
Database Table :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Emp](
[AutoID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
[Designation] [varchar](50) NULL,
[Salary] [int] NULL,
CONSTRAINT
[PK_Emp] PRIMARY KEY
CLUSTERED
(
[AutoID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS
= ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
Interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace WcfService1
{
[ServiceContract]
public interface ITransectionService
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Mandatory)]
int AddEmp(int
Salary,string Name, string
Designation);
}
}
Service :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Transactions;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Transactions;
namespace WcfService1
{
public class TransectionService : ITransectionService
{
[OperationBehavior(TransactionScopeRequired = true)]
public int AddEmp(int Salary, string
Name, string Designation)
{
int retval = 0;
Emp em = new Emp();
em.Name = Name;
em.Designation = Designation;
em.Salary = Salary ;
using (Database1Entities
ctx = new Database1Entities())
{
ctx.Emps.AddObject(em);
retval=ctx.SaveChanges();
}
return retval;
}
}
}
Webconfig:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="Database1Entities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider
connection string="data
source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\Database1.mdf;integrated
security=True;user
instance=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="transactionalWsatHttpBinding" transactionFlow="true" />
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
<services>
<service name="WcfService1.TransectionService">
<endpoint name="" address="http://localhost:56464/TransectionService.svc" bindingConfiguration="transactionalWsatHttpBinding" binding="wsHttpBinding" contract="WcfService1.ITransectionService" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
Client :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Data.SqlClient;
using System.Configuration;
namespace WCF_Transaction
{
class Program
{
static void Main(string[] args)
{
//We TransactionScope object to group the WCF services operations in one transaction.
//Here we are colling same service TWO times with different
objects.
using (TransactionScope
ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{
try
{
// declare object 1 to call servic method
WCF_Transaction.TransectionServiceServiceref.TransectionServiceClient Obj1 = new WCF_Transaction.TransectionServiceServiceref.TransectionServiceClient();
int A = Obj1.AddEmp(10000,"Employee1", "Manager");
// declare object 1 to call servic method
WCF_Transaction.TransectionServiceServiceref.TransectionServiceClient Obj2 = new WCF_Transaction.TransectionServiceServiceref.TransectionServiceClient();
int B = Obj1.AddEmp(2000,"Employee2", "Director");
Console.WriteLine(" Done , press enter to exit ");
ts.Complete();
}
catch
{
Console.WriteLine("Unable to process transaction,press enter to
exit ");
ts.Dispose();
}
Console.ReadLine();
}
}
}
}
OutPut:
transaction fails senerio not available in this demo. and when i use ts.Rollback() method..may example is not suitable ...but i can say is as per this demo can get basic idea about
ReplyDeleteTransactions in WCF.
...Waiting for next article....Lavi