Transaction support for XML Web services leverages support in the common language runtime, which is based on the same distributed transaction model found in Microsoft Transaction Server (MTS) and COM+ Services. This model is based on explicitly determining whether an object participates in a transaction, rather than writing specific code to handle delegation and callbacks for a transaction. For an XML Web service created using ASP.NET, you can declare the transaction behavior of an XML Web service by setting the TransactionOption attribute of the WebMethod attribute that applies to an XML Web service method. If an exception is thrown when the XML Web service method is executed, the transaction ends automatically; on the contrary, if no exception occurs, the transaction is automatically delegated.
The TransactionOption attribute of the WebMethod attribute specifies how an XML Web service method participates in a transaction. Although this declaration level represents a transaction logic, it is a step away from the actual transaction. The actual transaction occurs when a transaction object accesses a data source (such as a database or message queue). Transactions associated with this object automatically flow to the appropriate resource manager. A .NET Framework data provider like the .NET Framework Data Provider (for SQL Server or OLE DB) looks for transactions in the context of an object and catalogs them through a Distributed Transaction Coordinator (DTC, Distributed Transaction Coordinator). All transactions are generated automatically.
XML Web service methods can only participate in a transaction that is the root of a new transaction. As the root of a new transaction, all interactions with resource managers (such as servers running Microsoft SQL Server, Microsoft Message Queuing, and Microsoft Host Integration Server) maintain the ACID properties required to run robust distributed applications. XML Web service methods that call other XML Web service methods participate in different transactions because transactions do not flow through XML Web service methods.
Declare an XML Web serviceusing transactions from XML Web service methods
.
[C#]
<%@ WebService Language="C#" Class="Orders" %>
[Visual Basic]
<%@ WebService Language="VB" Class="Orders" %>
Add an assembly instruction to System.EnterpriseServices.
<%@ Assembly name="System.EnterpriseServices,Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" %>
Add references to the System.Web.Services and System.EnterpriseServices domain name spaces.
[C#]
using System.Web.Services;
using System.EnterpriseServices;
[Visual Basic]
Imports System.Web.Services
Imports System.EnterpriseServices
declares an XML Web service method and sets the TransactionOption property of the WebMethod attribute to TransactionOption.RequiresNew.
[C#]
[WebMethod(TransactionOption=TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName)
[Visual Basic]
<WebMethod(TransactionOption:=TransactionOption.RequiresNew)> _
Public Function DeleteAuthor(lastName As String) As Integer
The following code example shows an XML Web service using a single XML Web service method, calling DeleteDatabase. This XML Web service method performs a database operation within the scope of a transaction. If the database operation throws an exception, the transaction is automatically stopped; otherwise, the transaction is automatically committed.
[C#]
<%@ WebService Language="C#" Class="Orders" %>
<%@ Assembly name="System.EnterpriseServices,Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" %>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;
using System.EnterpriseServices;
public class Orders : WebService
{
[WebMethod(TransactionOption=TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName)
{
String deleteCmd = "DELETE FROM authors WHERE au_lname='" +
lastName + "'" ;
String exceptionCausingCmdSQL = "DELETE FROM NonExistingTable WHERE
au_lname='" + lastName + "'" ;
SqlConnection sqlConn = new SqlConnection(
"Persist Security Info=False;Integrated Security=SSPI;database=pubs;server=myserver");
SqlCommand deleteCmd = new SqlCommand(deleteCmdSQL,sqlConn);
SqlCommand exceptionCausingCmd = new
SqlCommand(exceptionCausingCmdSQL,sqlConn);
// This command should execute properly.
deleteCmd.Connection.Open();
deleteCmd.ExecuteNonQuery();
// This command results in an exception, so the first command is
// automatically rolled back. Since the XML Web service method is
// participating in a transaction, and an exception occurs, ASP.NET
// automatically aborts the transaction. The deleteCmd that
// executed properly is rolled back.
int cmdResult = exceptionCausingCmd.ExecuteNonQuery();
sqlConn.Close();
return cmdResult;
}
}
[Visual Basic]
<%@ WebService Language="VB" Class="Orders" %>
<%@ assembly name="System.EnterpriseServices" %>
Imports System
ImportsSystem.Data
Imports System.Data.SqlClient
Imports System.Web.Services
Imports System.Web.Util
Imports System.EnterpriseServices
Public Class Orders
<WebMethod(TransactionOption:=TransactionOption.RequiresNew)> _
Public Function DeleteAuthor (lastName as String) as Integer
Dim deleteCmdSQL As String = "DELETE FROM authors WHERE au_lname='" + _
lastName + "'"
Dim exceptionCausingCmdSQL As String = "DELETE FROM " + _
"NonExistingTable WHERE au_lname='" + lastName + "'"
Dim sqlConn As SqlConnection = New SqlConnection( _
"Persist Security Info=False;Integrated Security=SSPI;database=pubs;server=myserver")
Dim deleteCmd As SqlCommand = New SqlCommand(deleteCmdSQL,sqlConn)
Dim exceptionCausingCmd As SqlCommand = New _
SqlCommand(exceptionCausingCmdSQL,sqlConn)
' This command should execute properly.
deleteCmd.Connection.Open()
deleteCmd.ExecuteNonQuery()
' This command results in an exception, so the first command is
' automatically rolled back. Since the XML Web service method is
' participating in a transaction, and an exception occurs, ASP.NET
' automatically aborts the transaction. The deleteCmd that
' executed properly is rolled back.
Dim cmdResult As Integer = exceptionCausingCmd.ExecuteNonQuery()
sqlConn.Close()
Return cmdResult
End Function
End Class