ASP.NET を使用して作成した XML Web サービスでのトランザクションへの参加
XML Web サービスのトランザクション サポートは、共通言語ランタイムのトランザクション サポートを利用し、Microsoft Transaction Server (MTS) および COM+ サービスと同じ分散トランザクション モデルに基づいています。このモデルは、トランザクションのコミットおよびロールバックを処理する特定のコードを記述することではなく、オブジェクトがトランザクションに参加するかどうかを宣言によって決定することを基盤としています。ASP.NET を使用して作成した XML Web サービスの場合は、XML Web サービス メソッドに適用された WebMethod 属性の TransactionOption プロパティを設定することで、XML Web サービスのトランザクション動作を宣言できます。XML Web サービス メソッドの実行中に例外がスローされた場合、トランザクションは自動的に中止されます。その逆に、例外が発生しない場合は、トランザクションは自動的にコミットされます。
WebMethod 属性の TransactionOption プロパティは、XML Web サービス メソッドがトランザクションに参加する方法を指定します。この宣言レベルはトランザクションのロジックを表しますが、物理的トランザクションから 1 ステップ削除されたものです。物理トランザクションは、データベースやメッセージ キューなどのデータ リソースにトランザクション オブジェクトがアクセスするときに発生します。オブジェクトに関連付けられたトランザクションは、適切なリソース マネージャに自動的に送られます。.NET Framework Data Provider for SQL Server や .NET Framework Data Provider for OLE DB などの .NET Framework データ プロバイダは、オブジェクトのコンテキスト内でトランザクションを検索し、分散トランザクション コーディネータ (DTC: Distributed Transaction Coordinator) を通じてそのトランザクションに参加します。このトランザクション全体が自動的に発生します。
XML Web サービス メソッドがトランザクションに参加できるのは、新しいトランザクションのルートとしてだけです。新しいトランザクションのルートとして、Microsoft SQL Server、Microsoft メッセージ キュー (MSMQ: Microsoft Message Queuing)、および Microsoft Host Integration Server を実行するサーバーなどのリソース マネージャとのすべての対話で、安定した分散アプリケーションを実行するために必要な ACID プロパティを維持します。トランザクションは複数の XML Web サービス メソッド間を流れないため、他の XML Web サービス メソッドを呼び出す XML Web サービス メソッドは、異なるトランザクションに参加します。
XML Web サービス メソッドからトランザクションに参加するには
XML Web サービスを宣言します。
<%@ WebService Language="C#" Class="Orders" %> [Visual Basic] <%@ WebService Language="VB" Class="Orders" %>
Assembly ディレクティブを System.EnterpriseServices に追加します。
<%@ Assembly name="System.EnterpriseServices,Version=1.0.3300.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" %>
System.Web.Services 名前空間および System.EnterpriseServices 名前空間への参照を追加します。
using System.Web.Services; using System.EnterpriseServices; [Visual Basic] Imports System.Web.Services Imports System.EnterpriseServices
XML Web サービス メソッドを宣言し、WebMethod 属性の TransactionOption プロパティを TransactionOption.RequiresNew に設定します。
[ WebMethod(TransactionOption=TransactionOption.RequiresNew)] public int DeleteAuthor(string lastName) [Visual Basic] < WebMethod(TransactionOption:=TransactionOption.RequiresNew)> _ Public Function DeleteAuthor(lastName As String) As Integer
DeleteDatabase
という名前の 1 つの XML Web サービス メソッドを公開する XML Web サービスのコード例を次に示します。この XML Web サービス メソッドは、スコープがトランザクション内に指定されたデータベース操作を実行します。このデータベース操作によって例外がスローされた場合、トランザクションは自動的に停止します。それ以外の場合は、トランザクションは自動的にコミットされます。
<%@ 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
Imports System.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
メモ XML Web サービス メソッドを実装するメソッドが、そのメソッドを含んでいるかまたは関連付けられている、拡張子が .asmx のファイルへのインターネット要求が原因で呼び出されない場合は、TransactionOption プロパティの値は影響しません。これは、メソッドが属するクラスが Visual Studio .NET 内のプロジェクトのメンバであり、XML Web サービスがプロキシ クラスを使用して呼び出されていない場合に発生する可能性があります。Visual Studio .NET では、プロキシ クラスは Web 参照を追加したときに生成されます。
参照
トランザクション処理 | TransactionOption 列挙体 | TransactionOption プロパティ | ASP.NET を使用した XML Web サービスの作成