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. Collapse
<%@ WebService Language="C#" Class=" DBOperations " %>
- Add an Assembly directive to
System.EnterpriseServices
.Collapse<%@ Assembly name="System.EnterpriseServices" %>
- Add references to the
System.Web.Services
andSystem.EnterpriseServices
namespaces.Collapseusing System.Web.Services; using System.EnterpriseServices;
- Declare an XML Web service method, setting the
TransactionOption
property of theWebMethod
attribute toTransactionOption.RequiresNew
.
Collapse
[ 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. Collapse
<%@ 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: Collapse
[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
. Collapse
[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.
Indicates the transaction support of an XML Web service method.
[Visual Basic]Public Property TransactionOption As TransactionOption [C#]public TransactionOption TransactionOption {get; set;} [C++]public: __property TransactionOption get_TransactionOption(); public: __property void set_TransactionOption(TransactionOption); [JScript]public function get TransactionOption() : TransactionOption; public function set TransactionOption(TransactionOption);
Property Value
The transaction support of an XML Web service method. The default is Disabled.Remarks
XML Web service methods can only participate as the root object in a transaction, due to the stateless nature of the HTTP protocol. XML Web service methods can invoke COM objects that participate in the same transaction as the XML Web service method, if the COM object is marked to run within a transaction in the Component Services administrative tool. If an XML Web service method with a TransactionOption property of Required or RequiresNew invokes another XML Web service method with a TransactionOption property of Required or RequiresNew, each XML Web service method participates in its own transaction, because an XML Web service method can only act as the root object in a transaction.Item | Description |
---|---|
Disabled | Indicates that the XML Web service method does not run within the scope of a transaction. When a request is processed, the XML Web service method is executed without a transaction. [WebMethod(TransactionOption= TransactionOption.Disabled)] |
NotSupported | Indicates that the XML Web service method does not run within the scope of a transaction. When a request is processed, the XML Web service method is executed without a transaction. [WebMethod(TransactionOption= TransactionOption.NotSupported)] |
Supported | Indicates that the XML Web service method does not run within the scope of transactions. When a request is processed, the XML Web service is created without a transaction. [WebMethod(TransactionOption= TransactionOption.Supported)] |
Required | Indicates that the XML Web service method requires a transaction. Since XML Web service methods can only participate as the root object in a transaction, a new transaction will be created for the XML Web service method. [WebMethod(TransactionOption= TransactionOption.Required)] |
RequiresNew | Indicates that the XML Web service method requires a new transaction. When a request is processed, the XML Web service is created within a new transaction. [WebMethod(TransactionOption= TransactionOption.RequiresNew)] |
Example
[Visual Basic, C#] The example below begins a new transaction when the Transfer method is called.[Visual Basic] <%@ WebService Language="VB" Class="Bank"%> <%@ assembly name="System.EnterpriseServices,Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" %> Imports System Imports System.Web.Services Imports System.EnterpriseServices Public Class Bank Inherits WebService <WebMethod(TransactionOption := TransactionOption.RequiresNew)> _ Public Sub Transfer(Amount As Long, AcctNumberTo As Long, AcctNumberFrom As Long) Dim objBank As New MyCOMObject() If objBank.GetBalance(AcctNumberFrom) < Amount Then ' Explicitly abort the transaction. ContextUtil.SetAbort() Else ' Credit and Debit method explictly vote within ' the code for their methods whether to commit or ' abort the transaction. objBank.Credit(Amount, AcctNumberTo) objBank.Debit(Amount, AcctNumberFrom) End If End Sub End Class [C#] <%@ WebService Language="C#" Class="Bank"%> <%@ assembly name="System.EnterpriseServices,Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" %> using System; using System.Web.Services; using System.EnterpriseServices; public class Bank : WebService { [ WebMethod(TransactionOption=TransactionOption.RequiresNew) ] public void Transfer(long Amount, long AcctNumberTo, long AcctNumberFrom) { MyCOMObject objBank = new MyCOMObject(); if (objBank.GetBalance(AcctNumberFrom) < Amount ) // Explicitly abort the transaction. ContextUtil.SetAbort(); else { // Credit and Debit methods explictly vote within // the code for their methods whether to commit or // abort the transaction. objBank.Credit(Amount, AcctNumberTo); objBank.Debit(Amount, AcctNumberFrom); } } }
No comments:
Post a Comment