手順 2: コンポーネント間でトランザクションを拡張する
目標
この手順では、次の情報を学習します。
- トランザクション フロー
- トランザクションで複数のオブジェクトが投票する方法
説明
手順 1: トランザクション コンポーネント の作成では、Microsoft SQL Server Pubs データベースの作成者情報を更新する単純なトランザクション コンポーネントを記述する方法を示します。 手順 2 では、トランザクションが複数のコンポーネントにまたがって拡張された場合の動作を示します。
COM+ プログラミング モデルに合わせて、 UpdateAuthorAddress
は作業を完了する過程で別のコンポーネントを呼び出します。 2 番目のコンポーネント、 ValidateAuthorAddress
は、 作成者のアドレスを検証し、 結果を呼び出し元の UpdateAuthorAddress
に返します。
呼び出し元とは異なり、 ValidateAuthorAddress
は、トランザクションは必要ありませんが、呼び出し元のトランザクションには引き続き参加できます。 この手順では、次の図に示すように、そのトランザクション属性値が サポート対象に 設定され、既存のトランザクションが新しいオブジェクトに拡張されます。
サポートされている 属性値は 、 呼び出し元がトランザクションである場合にのみ、既存のトランザクションを拡張 (またはフロー) します。 UpdateAuthorAddress
呼び出しValidateAuthorAddress
の場合、COM+ は最初に呼び出し元のコンテキストを調び、それがトランザクションであるかどうかを確認します。 COM+ は、 ValidateAuthorAddress
に設定されているサービス属性を調べて、呼び出し元オブジェクトに割り当てられているのと同じトランザクション識別子を新しいオブジェクトに割り当てます。 このプロセスをより深く理解するには、「コンテキストのアクティブ化」を参照してください。
同じトランザクション識別子を共有するため、両方のオブジェクトが正常に作業を完了する必要があります。または、COM+ はトランザクションを中止します (Pubs データベースに加えられた変更を元に戻します)。
トランザクションに参加しているすべてのオブジェクトは、トランザクションのコミットまたは中止に投票します。 投票は、 UpdateAuthorAddress
コンポーネントを作成する手順 1 サンプル コードからの次の抽出に示すように、コードに投票命令を含めると明示的に行われます。
' Everything works.
contextstate.SetMyTransactionVote TxCommit
contextstate.SetDeactivateOnReturn True
Exit Sub
UnexpectedError:
' There's an error.
contextstate.SetMyTransactionVote TxAbort
contextstate.SetDeactivateOnReturn True
投票も、コンポーネントで行われるように暗黙的に ValidateAuthorAddress
行われます。 オブジェクトが宣言しない限り、COM+ は、オブジェクトが正常に作業を完了したが、非アクティブ化する準備ができていないことを前提としています。 COM+ では、次のような前提があります。
contextstate.SetMyTransactionVote TxCommit
contextstate.SetDeactivateOnReturn False
ValidateAuthorAddress
が呼び出し元に戻ると 、COM+ はその投票をコミットとして読み取ります。 COM+ は、トランザクションの最初のオブジェクトであるルート オブジェクト (この場合はUpdateAuthorAddress
オブジェクト) を非アクティブ化するまで、投票をカウントしません。
サンプル コード
この ValidateAuthorAddress
コンポーネントは、作成者の住所の単純なチェックを作成します。 UpdateAuthorAddress
は明示的に投票しないため、COM+ は既定の投票設定を使用します。
Option Explicit
'
' Purpose: This class is used for validating an author's address
' (presumably right before updating that address in the
' database).
'
' Notes: This component could be in a transaction or not; it doesn't
' matter because it doesn't touch any data in a database.
'
Public Function ValidateAuthorAddress( _
ByVal strAddress As String, _
ByVal strCity As String, _
ByVal strState As String, _
ByVal strZip As String) As Boolean
' Default is to validate unless something is found to be wrong.
ValidateAuthorAddress = True
' Invalidate authors who live in New York City
' and authors who live in Montana.
'
If strCity = "New York" And strState = "New York" Then
ValidateAuthorAddress = False
ElseIf strState = "Montana" Then
ValidateAuthorAddress = False
End If
' Done
End Function
まとめ
コンポーネントのトランザクション属性を Supported に設定すると、呼び出し元オブジェクトのトランザクションで新しいオブジェクトが作成される可能性があります。 COM+ は呼び出し元のコンテキストを調べて、新しいオブジェクトのトランザクション状態を判断します。 呼び出し元がトランザクションである場合、COM+ はトランザクションを新しいオブジェクトにフローします。
同じトランザクションに参加しているすべてのオブジェクトは、COM+ がオブジェクトのコンテキストから読み取る共通のトランザクション識別子を共有します。
トランザクション内の各オブジェクトは、他のオブジェクトとは無関係に投票します。 COM+ は、ルート オブジェクトが非アクティブ化されたときに投票をカウントします。
オブジェクトのトランザクション投票をコミットと中止の間で切り替えるには、COM+ がオブジェクトを非アクティブ化するか、COM+ がルート オブジェクトを非アクティブ化してトランザクションを終了します。 最後の投票設定のみがカウントされます。 IContextState インターフェイスと IObjectContext インターフェイスはメソッドを提供し、次の表に示すように同様の投票結果を生成します。 どちらのインターフェイスを使用しても、トランザクションで明示的に投票できます。
IContextState の 組み合わせメソッド IObjectContext と同等の メソッド SetMyTransactionVote txVote = TxCommit
SetDeactivateOnReturn bDeactivate = TrueSetComplete SetMyTransactionVote txVote = TxCommit
SetDeactivateOnReturn bDeactivate = FalseEnableCommit SetMyTransactionVote txVote = TxAbort
SetDeactivateOnReturn bDeactivate = TrueSetAbort SetMyTransactionVote txVote = TxAbort
SetDeactivateOnReturn bDeactivate = FalseDisableCommit COM+ は、コンポーネントが明示的に投票しない限り、オブジェクトの 投票を EnableCommit に相当するものに設定します。
明示的に投票すると、トランザクションの全体的な期間を短縮し、コストの高いリソース ロックを解放できます。