Creating transactional ASP.NET pages
Introduction
Many time our business rules require
that a certain set of operations be performed in a �batch�. The batch is atomic
i.e. if any of the operation from the batch fails all the operations are undone.
To achieve such functionality we frequently use transactions. Transactions offer
ACID properties (Atomicity, Consistency, Isolation and Durability). In ASP.NET
application transactions can be implemented at two levels:
- At component level : In this case you will write your
code that handles transactions and marks the transaction as successful or
fail. You will host such components in MTS or COM+.
- At page level : It might the case that you are not using components in
your ASP.NET pages. You can still use the transactional behavior by marking
the ASP.NET page to support transaction. ASP.NET also raises certain page
level events that are fired after transaction succeeds or fails.
In this article we will see how to
handle transactions in ASP.NET page itself.
Marking an ASP.NET page as Transactional
ASP.NET has a page level attribute
called Transaction which is used to mark that page as transactional. Following
code fragment will make the use of Transaction attribute clear :
<%@ Page Language="VB" Transaction="Required" %>
Once you mark the page as transactional, all the operations within that page
take place in a single transaction. You can commit or rollback the operations
depending on some business logic or other errors.
Importing Required Namespaces
Once you declare a page as
transactional you can decide whether to mark the transaction as successful
(COMMIT) or failure (ABORT). In ASP.NET you make use of a special namespace for
this purpose. The namespace is Microsoft.ComServices. You need to set reference
to assembly Microsoft.ComServices.dll and import the namespace in your page as
follows:
<%@ Assembly Name="Microsoft.ComServices.dll %>
<%@ Import Namespace="Microsoft.ComServices" %>
Note : If you are using Visual Studio.NET you can right click on references
folder in solution explorer and all a reference to the assembly.
Marking a transaction as successful or fail
Now that you have declared your page as transactional and imported required
namespaces, you can perform any operations and decide whether to mark the
transaction as successful or fail. To do this you use ContextUtil class provided
by Microsoft.ComServices namespace. The class has following static methods :
- SetComplete : This method marks a transaction as
successful and all the changes are committed to the database.
- SetAbort : This method marks the transaction as fail and any changes are
undone.
Following code fragment makes use of these methods clear :
Dim cnn as ADOConnection
Dim cmd as ADOCommand
Cnn=new ADOConnection(myconnectionstring)
Cnn.Open()
Cmd=new ADOCommand()
cmd.ActiveConnection=cnn
Try
cmd.CommandText="INSERT INTO Account_A VALUES(1001,�25000�)"
cmd.ExecuteNonQuery()
cmd.CommandText="DELETE FROM Account_B WHERE ID=1001"
cmd.ExecuteNonQuery()
ContextUtil.SetComplete()
Catch e as Exception
ContextUtil.SetAbort()
End Try
Here, we are inserting a record in Account_A table and at the same time
deleting the same record from Account_B table. We want that the row should be
deleted from Account_B table only if it has successfully inserted in Account_A
table also, the row should get inserted in Account_A table only if it gets
deleted from Account_B table. We therefore put the statements in try-catch block
for any errors. If there are no errors we COMMIT the transaction so that changes
are permanently written to the database. If any error occur during execution of
any of the statement we ABORT the transaction so that database state is
unaffected.
Transaction Events
You may want to display some error
message when transaction is committed or aborted or you may want to log the
information in some log file. ASP.NET page provides two page level events that
are fired when a transaction is committed or aborted. They are :
- Page_AbortTransaction
- Page_CommitTransaction
As the names suggest AbortTransaction event is fired when you call
ContextUtil.SetAbort method. Similarly, CommitTransaction event is fired when
ContextUtil.SetComplete method is called. Here is how the events look like:
Public Sub Page_AbortTransaction
(sender as object, e as EventArgs)
Response.write("Transaction Failed")
End Sub
Public Sub Page_CommitTransaction
(sender as object, e as EventArgs)
Response.write("Transaction Successful")
End Sub