手順 1: トランザクション コンポーネントの作成
目標
この手順では、次の情報を学習します。
- Microsoft Visual Basic でトランザクション コンポーネントを記述する方法
- COM+ サービスの既定の設定
- COM+ サービスを構成する方法
説明
このセクションで作成するコンポーネントである UpdateAuthorAddress コンポーネントは、Pubs データベース内の既存の作成者のアドレスを更新します。 Pubs データベースは、Microsoft SQL Server に付属するサンプル データベースです。 これには、著者名、住所、書籍タイトルなどの公開情報が含まれています。
Note
Pubs は、この入門で使用されるデータ ストアです。
UpdateAuthorAddress はデータ ストアを更新するため、次の図に示すように、トランザクションに作業を含め、クライアントがコンポーネントを呼び出すときに COM+ によってトランザクションが自動的に開始され、そのトランザクションにデータベース (リソース マネージャー) が登録されるようにすることをお勧めします。 (COM+ でのトランザクションの詳細については、以下を参照してください 。 COM+ Transactions.)
UpdateAuthorAddress をトランザクション コンポーネントにするには、次の手順が必要です。
コンポーネントを書き込む必要があります。 保護を強化するために、サブルーチンが追加され、COM+ がトランザクションでオブジェクトを作成したことを確認します。 また、エラーの回復を簡略化するために、基本的なエラー処理がコンポーネントに含まれています。 トランザクション検証とエラー処理により、コンポーネントの信頼性が向上します。 (UpdateAuthorAddress コンポーネントの完全な一覧については、手順 1 のサンプル コードを参照してください)。
コンポーネントを COM+ アプリケーションに追加し、アプリケーションをインストールした後、トランザクション属性を Required に設定する必要があります。これにより、COM+ によって各 UpdateAuthorAddress オブジェクトがトランザクションに作成されます。 コンポーネントのトランザクション属性を設定する方法については、「トランザクション属性の設定」を参照してください。
Note
コンポーネントにトランザクション属性を設定すると、COM+ がトランザクションに関して各オブジェクトを作成する方法が定義されます。 トランザクション属性値は、 無視、 サポートされていません、 サポート、 必須、および 新規が必要です。 Required 値は、コンポーネントの既定の属性値の 1 つではありません。
COM+ は、Just-In-Time (JIT) のアクティブ化とコンカレンシーを使用してトランザクション サービスをバインドします。 コンポーネントをトランザクションとして宣言すると、COM+ は JIT アクティブ化とコンカレンシー保護 (同期) も適用します。
サンプル コード
UpdateAuthorAddress コンポーネントは、Pubs データベースへの接続を開き、ユーザーが作成者の名前、アドレス、またはコントラクトの状態を変更できるようにします。 また、2 つ目のコンポーネントも呼び出します。これについては、「手順 2: 複数のコンポーネント間でのトランザクションの拡張」で 説明されています。
Microsoft Visual Basic プロジェクトで次のコードを使用するには、新しいActiveX.dll プロジェクトを開き、Microsoft ActiveX データ オブジェクト ライブラリと COM+ サービス タイプ ライブラリへの参照を追加します。
Note
この入門書のサンプル コードは、説明を目的としており、実際のステージングと運用環境では最も効率的ではない可能性があります。
Option Explicit
'
' Purpose: This class is used for updating an author's address.
'
' Notes: IMPT: This component implicitly assumes that it will
' always run in a transaction. Undefined results may
' otherwise occur.
'
'----------------------------------------------------------
' VerifyInTxn subroutine
' Verifies that this component is in a transaction.
' Throws an error if it is not.
'
Private Sub VerifyInTxn()
If Not GetObjectContext.IsInTransaction Then
' Transactions turned off.
Err.Raise 99999, "This component", "I need a transaction!"
End If
' Component is in a transaction.
End Sub
'----------------------------------------------------------
' UpdateAuthorAddress subroutine
' Procedure to update an author's address.
'
Public Sub UpdateAuthorAddress( _
ByVal strAuthorID As String, _
ByVal strPhone As String, _
ByVal strAddress As String, _
ByVal strCity As String, _
ByVal strState As String, _
ByVal strZip As String)
' Handle any errors.
On Error GoTo UnexpectedError
' Verify that component is in a transaction.
VerifyInTxn
' Get object context.
Dim objcontext As COMSVCSLib.ObjectContext
Set objcontext = GetObjectContext
' Get the IContextState object.
Dim contextstate As COMSVCSLib.IContextState
Set contextstate = objcontext
' Validate the new address information.
' The ValidateAuthorAddress function is described in Step 2.
Dim oValidateAuthAddr As Object
Dim bValidAddr As Boolean
Set oValidateAuthAddr = _
CreateObject("ComplusPrimer.ValidateAuthorAddress")
bValidAddr = oValidateAuthAddr.ValidateAuthorAddress( _
strAddress, strCity, strState, strZip)
If Not bValidAddr Then
Err.Raise 99999, "The UpdateAuthorAddress component", _
"The address of the author is incorrect!"
End If
' Open the connection to the database.
Dim conn As ADODB.Connection
Set conn = CreateObject("ADODB.Connection")
' Specify the OLE DB provider.
conn.Provider = "SQLOLEDB"
' Connect using Windows Authentication.
Dim strProv As String
strProv = "Server=MyDBServer;Database=pubs;Trusted_Connection=yes"
' Open the database.
conn.Open strProv
' Execute the query.
conn.Execute "update authors set phone= '" & strPhone & "'" & _
" set address= '" & strAddress & "'" & _
" set city= '" & strCity & "'" & _
" set state= '" & strState & "'" & _
" set zip= '" & strZip & "'" & _
" where au_id = '" & strAuthorID & "'"
' Close the connection.
conn.Close
' Get rid of the connection.
Set conn = Nothing
' Everything works--commit the transaction.
contextstate.SetMyTransactionVote TxCommit
contextstate.SetDeactivateOnReturn True
Exit Sub
UnexpectedError:
' There's an error.
contextstate.SetMyTransactionVote TxAbort
contextstate.SetDeactivateOnReturn True
End Sub
まとめ
- COM+ では、既定の属性値が割り当てられます。 ほとんどのサービス属性を再構成できます。
- コンポーネントのトランザクション属性を Required に設定すると、COM+ はそのコンポーネントの各インスタンスをトランザクションに作成する必要がありますが、必ずしも新しいトランザクションを開始する必要はありません。
- トランザクションが存在することを確認すると、コンポーネントのトランザクション属性値が、 無視 や サポートされていないなどの非トランザクション値に誤ってリセットされなかったことが確認されます。
- エラーを処理すると、コンポーネントの信頼性が高くなり、トラブルシューティングが簡単になります。
- COM+ では、トランザクション コンポーネントに 対して JIT アクティブ化 と コンカレンシー保護 サービスが適用されます。
- 完了したらデータベース接続を閉じると、同じトランザクション内の別のコンポーネントが接続プールからの接続を再利用できます。 (接続プーリングは、 オブジェクト プールと混同しないでください)。
関連トピック