現在オフラインです。再接続するためにインターネットの接続を待っています

Visual C# コンポーネントで COM+ トランザクションを使用する方法

Microsoft Visual Basic .NET については、次の資料を参照してください。315707

この資料の内容

概要
この資料では、Visual C# クラスで COM+ (コンポーネント サービス) トランザクションを使用する方法について手順を追って説明します。一連のデータベース操作は 1 つの単位と見なされます。すべての操作が成功すれば、トランザクションは成功しますが、操作が 1 つでも失敗すると、トランザクション全体が失敗します。後者の場合、実行したデータベース操作は基になるデータベースにポストされません。

先頭に戻る

必要条件

必要なハードウェア、ソフトウェア、ネットワーク インフラストラクチャ、技術と知識、および Service Pack は次のとおりです。
  • Microsoft Windows 2000 Server SP1
  • Microsoft Internet Information Server (IIS) 4.0 またはインターネット インフォメーション サービス 5.0 以降
  • Microsoft Internet Explorer 5.0、5.5、または 6.0
この資料は、以下について詳しい知識のあるユーザーを対象としています。
  • トランザクションの概念と処理
  • COM+ (コンポーネント サービス)
先頭に戻る

COM+ トランザクション サービス

トランザクション処理は、Microsoft .NET Framework の System.EnterpriseServices 名前空間を使用して実装できます。COM+ トランザクション サービスにアクセスするには、次の手順に従ってクラスを作成します。
  1. Visual Studio .NET または Visual Studio 2005 を起動します。
  2. [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
  3. [プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [クラス ライブラリ] をクリックします。[プロジェクト名] ボックスに prjEnterprise と入力し、[OK] をクリックします。

    : Visual Studio 2005 では、[プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [クラス ライブラリ] をクリックします。プロジェクト名として prjEnterprise を指定します。
  4. デフォルトで Class1 が作成されます。
  5. ソリューション エクスプローラで、[参照設定] を右クリックし、[参照の追加] をクリックします。
  6. [参照の追加] ダイアログ ボックスが表示されます。[.NET] タブの [コンポーネント名] の下にある [System.EnterpriseServices] をダブルクリックします。
  7. [選択されたコンポーネント] の下に System.EnterpriseServices が表示されていることを確認します。[OK] をクリックします。
  8. Class1.cs ファイルの先頭に、次のコードを追加します。
    using System.EnterpriseServices;using System.Data.SqlClient;
  9. Class1.cs ファイルに clsES という名前の新しいクラスを追加します。
  10. COM+ トランザクション サービスを使用するには、クラス (clsES) が次のように ServicedComponent から機能を継承する必要があります。
    public class clsES : ServicedComponent
  11. Transaction 属性を使用して、次のようにクラスのトランザクション サポートのレベルを指定します。
    [Transaction(TransactionOption.Required)]public class clsES : ServicedComponent
  12. clsES クラスに 4 つの入力整数パラメータを受け取るメソッドを作成し、dbAccess という名前を付けます。最初の 2 つのパラメータで商品 ID (ProductID) とその商品の受注数 (UnitsOnOrder) を入力します。次の 2 つのパラメータで商品 ID とその商品の在庫数 (UnitsInStock) を入力します。このメソッドは、指定したこれらの商品 ID に対して一連のデータベース操作を実行し、これらがトランザクションとして処理されます。
    void dbAccess(int pID1,int onOrder, int pID2, int inStock)
  13. dbAccess メソッドで、Northwind データベースの SQL 接続オブジェクトを作成し、接続を開きます。データベース操作は、次のデータベースを使用して行います。

    : 使用する SQL Server サーバーの値に合わせて、次の接続文字列パラメータを変更してください。
    SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;");				Conn.Open();
  14. try ブロックを設定し、データベース処理中に発生する例外を捕捉します。これらの例外をキャッチして、トランザクションを中断する必要があります。try ブロックには、データベース操作が 2 つ含まれます。操作ごとに、指定した商品 (Products) テーブル レコード内の異なるフィールドが更新されます。
     try { 
  15. 商品テーブルに対して最初の更新を実行します。最初の 2 つの入力パラメータで指定された値を使用して、ID が pID1 の商品について、UnitsOnOrder フィールドを onOrder 値に更新します。この SQL 更新の実行には、次の SQL コマンドを使用します。
    SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn);				sqlCommand.ExecuteNonQuery();
  16. 商品テーブルに対してもう一度更新を実行します。3 番目および 4 番目の入力パラメータで指定された値を使用して、ID が pID2 の商品について、UnitsInStock フィールドを inStock 値に更新します。この SQL 更新の実行には、次の SQL コマンドを使用します。
    sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2;				sqlCommand.ExecuteNonQuery();
  17. これらの更新は COM+ トランザクションの一部であるため、1 つの単位としてコミットされます。System.EnterpriseServices 名前空間に含まれる contextUtil クラスの setComplete メソッドは、エラーがスローされなかった場合に、トランザクション (この場合は 2 回の更新) をコミットするために使用されます。
    ContextUtil.SetComplete();
  18. Northwind データベースへの接続を閉じます。
    Conn.Close();}
  19. トランザクション全体を中断できるように、SQL コマンドの実行中に発生する例外をキャッチする必要があります。
    catch(Exception e){ 
  20. System.EnterpriseServices 名前空間に含まれる contextUtil クラスの setAbort メソッドを使用して、トランザクション全体を中断します。最初の更新が成功し、2 回目の更新が失敗すると、どちらの更新も商品テーブルにポストされません。キャッチされた例外は呼び出し元にスローされ、トランザクションが失敗したことが通知されます。
    ContextUtil.SetAbort();				throw e;}
  21. このコンポーネントが適切に機能するには、コンポーネントに厳密な名前を付ける必要があります。厳密な名前を作成し、厳密な名前を使用してアセンブリを署名します。これを行うには、次の手順を実行します。
    1. Visual Studio .NET のコマンド プロンプトで sn.exe -k snEnterprise.snk と入力し、キー ファイルを作成します。厳密な名前を使用してアセンブリを署名する方法の詳細については、.NET Framework SDK ドキュメントを参照してください。
    2. snEnterprise.snk をプロジェクト フォルダにコピーします。
    3. AssemblyInfo.cs で、他のアセンブリ属性のステートメントの前または後に、次のコード行を追加します。
      [assembly: AssemblyKeyFileAttribute("..\\..\\snEnterprise.snk")]		
    4. プロジェクトを保存してビルドします。
先頭に戻る

完全なコード リスト



: 使用する SQL Server サーバーの値に合わせて、次の接続文字列パラメータを変更してください。
using System;using System.Data;using System.Data.SqlTypes;using System.Data.Common;using System.EnterpriseServices;using System.Data.SqlClient;namespace prjEnterprise{		[Transaction(TransactionOption.Required)]public class clsES:ServicedComponent	{		public SqlConnection Conn;		public void dbAccess(int pID1, int onOrder, int pID2, int inStock)		{			try			{							SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;");				Conn.Open();				SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn);				sqlCommand.ExecuteNonQuery();								sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2;				sqlCommand.ExecuteNonQuery();				ContextUtil.SetComplete();				Conn.Close();			}			catch(Exception e)			{				ContextUtil.SetAbort();							throw e;			}			finally			{			}		}	}	}

先頭に戻る

動作の検証

コードをテストするには、clsES プロジェクトを使用するコンソール アプリケーションを作成します。トランザクションが成功し、指定した商品の UnitsOnOrder フィールドと UnitsInStock フィールドが更新される場合と、指定した製品 ID が商品テーブルに存在しないため、指定した製品の UnitsOnOrder フィールドの更新が成功し、商品の UnitsInStock フィールドの更新が失敗する場合があります。後者の場合、トランザクションは失敗し、トランザクションは無視されます。
  1. Visual Studio .NET または Visual Studio 2005 で、[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
  2. [プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [コンソール アプリケーション] をクリックします。

    : Visual Studio 2005 では、[プロジェクトの種類] ボックスの一覧の [Visual C# プロジェクト] をクリックし、[テンプレート] ボックスの一覧の [コンソール アプリケーション] をクリックします。
  3. [プロジェクト名] ボックスに testES と入力し、[ソリューションに追加] をクリックします。
  4. [OK] をクリックして、このプロジェクトをソリューションに追加します。
  5. clsES をテストするには、testES に参照を追加する必要があります。ソリューション エクスプローラで、追加された [testES] の下の [参照設定] を右クリックし、[参照の追加] をクリックします。
  6. [参照の追加] ダイアログ ボックスが表示されます。[プロジェクト] タブで [prjEnterprise] をダブルクリックします。
  7. [選択されたコンポーネント] の下に参照が表示されます。[OK] をクリックして、この参照をプロジェクトに追加します。
  8. System.EnterpriseServices ライブラリへの参照をプロジェクトに追加します。ソリューション エクスプローラで、[参照設定] を右クリックし、[参照の追加] をクリックします。
  9. [参照の追加] ダイアログ ボックスが表示されます。[.NET] タブの [コンポーネント名] の下にある [System.EnterpriseServices] をダブルクリックします。
  10. [選択されたコンポーネント] の下に System.EnterpriseServices が表示されていることを確認します。[OK] をクリックします。
  11. ソリューション エクスプローラで [testES] を右クリックし、[スタートアップ プロジェクトに設定] をクリックします。
  12. Class1 クラスの Main 関数に、次のソース コードを貼り付けます。
    	prjEnterprise.clsES myTest = new prjEnterprise.clsES();				try 				{					myTest.dbAccess(1, 777, 2, 888);					Console.WriteLine("TRANSACTION ONE -- SUCCESS");					myTest.dbAccess(1, 5, 2, -20);					Console.WriteLine("TRANSACTION TWO -- SUCCESS");				}				catch (Exception e)				{					Console.WriteLine("TRANSACTION FAILURE");				}
  13. F5 キーを押してプログラムをテストします。

    手順 12. のコードでは、dbAccess への最初の呼び出しは成功します。Product 1 および Product 2 は商品テーブルに含まれています。Product 1 の UnitsOnOrder フィールドが 777 に更新され、Product 2 の UnitsInStock フィールドが 888 に更新されます。このトランザクションが成功したため、出力ウィンドウに次のメッセージが表示されます。
    TRANSACTION ONE - SUCCESS


    dbAccess への 2 回目の呼び出しは失敗します。そのため、dbAccess の商品テーブルの更新ステートメントはデータベースにポストされません。Product 1 の UnitsOnOrder フィールドを 5 に更新できますが、Product 2 では UnitsInStock フィールドを -20 に設定できません。商品テーブルの定義の制約により、inStock では負の数値を使用できません。

    したがって、dbAccess への呼び出しが失敗し、トランザクション全体が失敗します。Products テーブルは、dbAccess への呼び出し前の状態から変更されません。dbAccess からのトランザクション失敗の通知が catch ステートメントによって処理され、出力ウィンドウに次のエラー メッセージが表示されます。
    TRANSACTION FAILURE
  14. SQL Server のエンタープライズ マネージャを使用して、Northwind の Products テーブルの内容を検証します。Product 1 を確認すると、UnitsOnOrder フィールドが 777 となっています。Product 2 を確認すると、UnitsInStock フィールドが 888 となっています。このことから、これらのフィールドを別の値に更新するための 2 回目の dbAccess の呼び出しが失敗したことがわかります。
先頭に戻る

トラブルシューティング

  • COM+ サービスを使用するプロジェクトに厳密な名前が付いていることを確認します。
  • COM+ サービスを使用するクラスは、サービス コンポーネントから継承する必要があります。サービス コンポーネントは、System.EnterpriseServices 名前空間にあります。
  • デバッグ時、トランザクションがコミットまたは中断される前に、トランザクションがタイムアウトすることがあります。タイムアウトを回避するには、トランザクション属性のタイムアウト プロパティを使用します。次の例では、関連するメソッドがタイムアウトせずにトランザクションを完了するための時間は 1,200 秒です。
    [Transaction(TransactionOption.Required,timeout:=1200)]
先頭に戻る
関連情報
詳細については、次の MSDN (Microsoft Developer Network) Web サイトを参照してください。
COM+ Integration: How .NET Enterprise Services Can Help You Build Distributed Applications
http://msdn.microsoft.com/msdnmag/issues/01/10/complus/default.aspx
先頭に戻る
プロパティ

文書番号:816141 - 最終更新日: 10/04/2006 00:08:58 - リビジョン: 3.2

Microsoft Visual C# .NET 2003 Standard Edition, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# 2005

  • kbcomplusobj kbsqlprog kbsqlclient kbdatabase kbhowtomaster KB816141
フィードバック