Hi Friends,
In this
article, I will first explain what is transaction and what are the properties
of transaction and then I will try to explain how we can implement transactions
in WCF service. So we will create WCF services which do database transactions
and then check the transaction. I will first understand the steps how to enable
transactions in WCF services. At the end of the article, I will try to force an
error and see how the transaction is rolled back after the error.
What is Transactions?
A transaction
is a unit of work that is performed against a database. Transactions are units
or sequences of work accomplished in a logical order, whether in a manual
fashion by a user or automatically by some sort of a database program.
Properties of Transactions:
Transactions
have the following four standard properties, usually referred to by the acronym
ACID:
·
Atomicity: ensures that all operations within
the work unit are completed successfully; otherwise, the transaction is aborted
at the point of failure, and previous operations are rolled back to their
former state.
·
Consistency: ensures that the database properly
changes states upon a successfully committed transaction.
·
Isolation: enables transactions to operate
independently of and transparent to each other.
·
Durability: ensures that the result or effect
of a committed transaction persists in case of a system failure.
There are easy 5 steps for setting
transactions in WCF
Step 1: For service operation Setting.
Create a WCF
Service for Account and Enable TransactionFlowOption Mandatory
There are 3
modes for transaction flow option
• Mandatory Transaction must be flowed.
• NotAllowed A transaction should not be flowed. This is the default value.
In the below
service I creates one Service contract IAccountService and two Service
operations Deposit and Withdraw for particular Account ID a
[ServiceContract]
public
interface IAccountService
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Mandatory)]
[FaultContract(typeof(ErrorInfo))]
void Deposit(int
AccountId, decimal amount);
[OperationContract]
[TransactionFlow(TransactionFlowOption.Mandatory)]
[FaultContract(typeof(ErrorInfo))]
void WithDraw(int
AccountId, decimal amount);
}
Step 2: In Operational Behavior Setting
In Operation Behavior we have to enable TransactionScopeRequired = true and TransactionAutoComplete=true
·
TransactionScopeRequired: indicates whether the method requires
a transaction scope for its execution.
·
TransactionAutoComplete: indicates whether to automatically
complete the current transaction scope if no unhandled exceptions occur.
[ServiceBehavior(TransactionIsolationLevel=System.Transactions.IsolationLevel.Serializable)]
public class AccountService:IAccountService
{
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
public void
Deposit(int AccountId, decimal
amount)
{
//Your Code Here
}
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
public void
withDraw(int AccountId, decimal amount)
{
//Your Code Here
}
}
Step 3: Enable Transaction Flow using
WCF Service Config File
Binding - There are only few bindings in WCF
that can support transaction, these are NetTcpBinding, NetNamedPipeBinding, WSHttpBinding,
WSDualHttpBinding, and WSFederationHttpBinding. So, in order to configure
transaction, one has to make a choice out of such bindings. Though these
bindings do have transaction support but by default it is disabled, so one has
to make them enabled.
We also need
to enable transactions for
wsHttpBinding
by setting the transactionFlow
attribute to true
.
<bindings>
<wsHttpBinding>
<binding name="WsHttpConfig" transactionFlow="true">
<reliableSession enabled="true" />
</binding>
</wsHttpBinding>
</bindings>
Also give this setting to bindingConfiguration
<services>
<service behaviorConfiguration="MetaBehavior" name="WCFClassLibrary.AccountService">
<endpoint address="BankService" binding="wsHttpBinding" bindingConfiguration="WsHttpConfig"
name="BankService_http" contract="WCFClassLibrary.IAccountService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8055"
/>
</baseAddresses>
</host>
</service>
</services>
Step 4: On the Client Side Use
TrasactionScope
We need to
use TrasactionScope Attribute on to the client side for Transaction.
Create the TrasactionScope
to execute the commands, guaranteeing that both commands can commit or roll
back as a single unit of work.
using (TransactionScope t = new
TransactionScope())
{
AccountService.AccountServiceClient proxy = new AccountService.AccountServiceClient();
proxy.Deposit(1, 2000);
proxy.WithDraw(2, 200);
t.Complete();
proxy.Close();
}
Step 5: Check the Transactions is
Working or not
In the
Withdraw method we are checking that if the Account balance is less than 500 then
we are throwing the fault exception and Transaction is rollback
if
(accountBalance - amount < 500)
throw
new FaultException<ErrorInfo>(new ErrorInfo() { ErrorCode = "200",
ErrorDescription = "InSufficient Balance
found" }, "InSufficient Balance
found");
In this way you
can test the Transactions is working or not on the client side.
I have
attached Code snippet for that. Please download this.
Happy Programming!!
If you have any query mail
me to Sujeet.bhujbal@gmail.com
Regards
Sujeet Bhujbal
------------------------------------------------------------------------------------------------------------
Personal Website :-http://sujitbhujbal.wordpress.com/
Facebook :-www.facebook.com/sujit.bhujbal
CodeProject:-http://www.codeproject.com/Members/Sujit-Bhujbal
Linkedin :-http://in.linkedin.com/in/sujitbhujbal
Stack-Exchange: http://stackexchange.com/users/469811/sujit-bhujbal
Twitter :-http://twitter.com/SujeetBhujbal
JavaTalks :-http://www.javatalks.com/Blogger/sujit9923/
------------------------------------------------------------------------------------------------------
No comments:
Post a Comment