Transactions in ASP.NET WebServices






2.97/5 (17 votes)
Jun 13, 2004
3 min read

82935
Article about transaction and transaction flow in ASP.NET webservices.
Introduction
The transaction support for XML Web services created using ASP.NET is based on the same distributed transaction model found in the COM+ Services. This model is based on declaring attributes to decide whether an object participates in a transaction, rather than writing specific code to commit / roll back a transaction.
Once an XML Web service method is marked to participate in a transaction, it will automatically execute within the scope of a transaction. You can control an object's transactional behavior by setting a transaction attribute value on XML Web service method. The attribute value, in turn, determines the transactional behavior of the instantiated object. Thus, based on the declared attribute value, an object will automatically participate in an existing or ongoing transaction, be the root of a new transaction, or never participate in a transaction at all.
In an XML Web service created using ASP.NET, you can declare the web method’s transactional behavior by setting the TransactionOption
property of the WebMethod
attribute applied to an XML Web service method. If an exception is thrown while the XML Web service method is executing, the transaction is automatically aborted; conversely, if no exception occurs, the transaction is automatically committed.
Lets look at the TransactionOption
enumeration:
Disabled
: Ignores any transaction in the current context.NotSupported
: Creates the component in a context with no governing transaction.Required
: Shares a transaction if one exists, and creates a new transaction if necessary.RequiresNew
: Creates the component with a new transaction, regardless of the state of the current context.Supported
: Shares a transaction, if one exists.
To participate in a transaction from an XML Web service method:
- Declare an XML Web service.
<%@ WebService Language="C#" Class=" DBOperations " %>
- Add an Assembly directive to
System.EnterpriseServices
.<%@ Assembly name="System.EnterpriseServices" %>
- Add references to the
System.Web.Services
andSystem.EnterpriseServices
namespaces.using System.Web.Services; using System.EnterpriseServices;
- Declare an XML Web service method, setting the
TransactionOption
property of theWebMethod
attribute toTransactionOption.RequiresNew
.
[ WebMethod(TransactionOption=TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName)
The following code example shows an XML Web service that exposes a single XML Web service method, called DBOperations
. This XML Web service method performs a database operation that is scoped within a transaction. If the database operation does throw an exception, the transaction is automatically stopped; otherwise, the transaction is automatically committed.
<%@ WebService Language="C#" Class=" DBOperations " %>
<%@ Assembly name="System.EnterpriseServices" %>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;
using System.EnterpriseServices;
public class DBOperations : WebService
{
[ WebMethod(TransactionOption=TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName)
{
String delCmdSql =
"DELETE FROM authors WHERE au_lname='" + lastName + "'" ;
String exceptionCausingCmdSQL =
"DELETE FROM NonExistingTable WHERE au_lname='" + lastName + "'" ;
SqlConnection myCon =
new SqlConnection("user id=sa;database=pubs;server=myserver");
SqlCommand delCmd = new SqlCommand(delCmdSQL,myCon);
SqlCommand exceptionCausingCmd = new
SqlCommand(exceptionCausingCmdSQL,myCon);
// This command should execute properly.
delCmd.Connection.Open();
delCmd.ExecuteNonQuery();
// This command results in an exception, so the first command is
// automatically rolled back.
int cmdResult = exceptionCausingCmd.ExecuteNonQuery();
myCon.Close();
return cmdResult;
}
}
Transactions across WebServices
Let us look at an example of how the transaction occurs across XML Web service methods.
Consider we are having two servers Server1 and Server2. Server1 hosts XML Web Services WService1 and WService2. Server2 hosts WService3.
WService1 exposes a Web method named WMethod1
, WService2 exposes Wmethod2
, and WService3 exposes Wmethod3
. The Wmethod1
of WService1 is shown in the following code segment:
[WebMethod(TransactionOption.RequiresNew)]
public void WMethod1 ()
{
Server1. WService2 Service2 = new Server1. WService2 ();
Server2.WService3 Service3 = new Server2. WService3 ();
Service2.WMethod2();
Service3.WMethod3();
}
The TransactionOption
property of WMethod2
and WMethod3
are set to TransactionOption.Required
.
[WebMethod(TransactionOption.Required)]
public void WMethod2 ()
{
//Code to update a row in a table
}
[WebMethod(TransactionOption.Required)]
public void WMethod3 ()
{
//Code to update a row in another table
}
Develop a client application named myApp that consumes Wmethod1
of WService1. Run myApp. While WMethod1
is calling WMethod3
, close myApp.
What is the most likely result? What do you expect? A roll back of the updates made by WMethod2
and WMethod3
?
No, the Answer is Wmethod1
continues processing, and whatever updates that are made by the WMethod2
and WMethod3
persists, because transactions do not flow across XML Web service methods.
XML Web service methods can only participate in a transaction as the root of a new transaction. XML Web service methods that call other XML Web service methods participate in different transactions, as transactions do not flow across XML Web service methods.