ICrmCompensator
COM公式ドキュメント
Microsoft Visual C++ を使用する際に、非構造化ログレコードを CRM コンペンセーターへ配信します。
解説(Remarks)
CRM クラークは、ICrmLogControl::RegisterCompensator メソッドを使用して CRM コンペンセーターの CLSID を判別します。次に、この CRM コンペンセーターの CLSID を指定して CoCreateInstance を呼び出し、続いて ICrmCompensator インターフェイスと ICrmCompensatorVariants インターフェイスの両方について QueryInterface を呼び出します。
メソッド 10
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
CRM コンペンセーターに ICrmLogControl インターフェイスを渡し、トランザクション完了時にさらにログレコードを書き込めるようにします。
| pLogControl | ICrmLogControl* | inoptional | CRM クラークの ICrmLogControl インターフェイスへのポインター。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
CRM コンペンセーターのエラーは、この特定の CRM コンペンセーター CLSID に対して (レジストリフラグにより) 明示的にオーバーライドされていない限り、サーバープロセスの failfast を引き起こします。詳細については、COM+ CRM Registry Settings を参照してください。
トランザクション完了の prepare フェーズであること、およびレコードがこれから配信されることを CRM コンペンセーターに通知します。(ICrmCompensator.BeginPrepare)
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
prepare フェーズ中に、ログレコードを順方向の順序で配信します。
| crmLogRec | CrmLogRecordRead | in | ログレコード。CrmLogRecordRead 構造体として渡されます。 |
| pfForget | BOOL* | out | 配信されたレコードを破棄すべきかどうかを示します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
非構造化ログレコードは CrmLogRecordRead 構造体として配信されます。この構造体には、ユーザーデータ (単一の BLOB として) に加えて、人手による補償が必要な場合のデバッグや障害調査に役立つ可能性のあるフィールドがいくつか含まれています。dwCrmFlags メンバーはビットフィールドで、このレコードが途中で破棄されたかどうか、いつ書き込まれたかに関する追加情報を提供します。dwSequenceNumber メンバーは、ログレコードのシーケンス番号を提供します。ほとんどの場合、シーケンス番号は連番ですが、CRM コンペンセーターに配信されない内部ログレコードがあるため、必ずしも連続しているとは限りません。
CRM ワーカーによってログレコードがまったく書き込まれない場合、BeginPrepare メソッドと EndPrepare メソッドは受信されますが、PrepareRecord メソッドの呼び出しはありません。これは、prepare 時にのみログレコードを書き込む CRM コンペンセーターに対応するためです。
CRM コンペンセーターは、このメソッドから戻る際に forget フラグを設定することで、このフェーズ中に配信されたレコードを破棄することを選択できます。
prepare フェーズ中に利用可能なすべてのログレコードを受け取ったことを CRM コンペンセーターに通知します。(ICrmCompensator.EndPrepare)
| pfOkToPrepare | BOOL* | out | prepare フェーズが成功したかどうかを示します。成功した場合は、このトランザクションをコミットしてよいことを意味します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
トランザクション完了の commit フェーズであること、およびレコードがこれから配信されることを CRM コンペンセーターに通知します。
| fRecovery | BOOL | in | このメソッドがリカバリー中に呼び出されているか (TRUE)、通常処理中に呼び出されているか (FALSE) を示します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
リカバリー中は、commit フェーズまたは abort フェーズが prepare フェーズなしでコンペンセーターに受信されます。また、クライアントが abort を開始することを決定した場合、通常処理中でも abort フェーズが prepare フェーズなしで受信されることがあります。
CRM コンペンセーターは、prepare フェーズと commit/abort フェーズの間で状態が維持されることに依存すべきではありません。CRM インフラストラクチャは、必要に応じてこれら 2 つのフェーズの間で CRM コンペンセーターを解放することができます。ただし、Begin-Record-End の呼び出しの間では状態が維持され、CRM コンペンセーターはトランザクション結果の各メソッドが配信される前に必ず ICrmLogControl インターフェイスを取得します。
commit フェーズ中に、ログレコードを順方向の順序で配信します。
| crmLogRec | CrmLogRecordRead | in | ログレコード。CrmLogRecordRead 構造体として渡されます。 |
| pfForget | BOOL* | out | 配信されたレコードを破棄すべきかどうかを示します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
このメソッドは、書き込まれたログレコードごとに 1 回ずつ、CRM コンペンセーターによって複数回受信される可能性があります。ログレコードがまったく書き込まれない場合、BeginCommit メソッドと EndCommit メソッドは受信されますが、CommitRecord メソッドの呼び出しはありません。
CRM コンペンセーターは、このメソッドから戻る際に forget フラグを設定することで、このフェーズ中に配信されたレコードを破棄することを選択できます。
commit フェーズ中に利用可能なすべてのログレコードを配信し終えたことを CRM コンペンセーターに通知します。(ICrmCompensator.EndCommit)
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
トランザクション完了の abort フェーズであること、およびレコードがこれから配信されることを CRM コンペンセーターに通知します。(ICrmCompensator.BeginAbort)
| fRecovery | BOOL | in | このメソッドがリカバリー中に呼び出されているかどうかを示します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
クライアントが abort を開始することを決定した場合、abort フェーズは通常処理中に prepare フェーズなしで受信されることがあります。
CRM コンペンセーターは、prepare フェーズとこのフェーズの間で状態が維持されることに依存すべきではありません。CRM インフラストラクチャは、必要に応じてこれら 2 つのフェーズの間で CRM コンペンセーターを解放することができます。ただし、Begin-Record-End の呼び出しの間では状態が維持され、CRM コンペンセーターはトランザクション結果の各メソッドが配信される前に必ず ICrmLogControl インターフェイスを取得します。
abort フェーズ中に、ログレコードを CRM コンペンセーターに配信します。(ICrmCompensator.AbortRecord)
| crmLogRec | CrmLogRecordRead | in | ログレコード。CrmLogRecordRead 構造体として渡されます。 |
| pfForget | BOOL* | out | 配信されたレコードを破棄すべきかどうかを示します。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
ログレコードは、書き込まれた順序とは逆の順序で配信されます。このメソッドは、書き込まれたログレコードごとに 1 回ずつ、CRM コンペンセーターによって複数回受信される可能性があります。ログレコードがまったく書き込まれない場合、BeginAbort メソッドと EndAbort メソッドは受信されますが、AbortRecord メソッドの呼び出しはありません。
CRM コンペンセーターは、このメソッドから戻る際に forget フラグを設定することで、このフェーズ中に配信されたレコードを破棄することを選択できます。
abort フェーズ中に利用可能なすべてのログレコードを受け取ったことを CRM コンペンセーターに通知します。(ICrmCompensator.EndAbort)
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_ICrmCompensator "{BBC01830-8D3B-11D1-82EC-00A0C91EEDE9}" #usecom global ICrmCompensator IID_ICrmCompensator "{}" #comfunc global ICrmCompensator_SetLogControl 3 sptr #comfunc global ICrmCompensator_BeginPrepare 4 #comfunc global ICrmCompensator_PrepareRecord 5 int,var #comfunc global ICrmCompensator_EndPrepare 6 var #comfunc global ICrmCompensator_BeginCommit 7 int #comfunc global ICrmCompensator_CommitRecord 8 int,var #comfunc global ICrmCompensator_EndCommit 9 #comfunc global ICrmCompensator_BeginAbort 10 int #comfunc global ICrmCompensator_AbortRecord 11 int,var #comfunc global ICrmCompensator_EndAbort 12 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_ICrmCompensator "{BBC01830-8D3B-11D1-82EC-00A0C91EEDE9}" #usecom global ICrmCompensator IID_ICrmCompensator "{}" #comfunc global ICrmCompensator_SetLogControl 3 sptr #comfunc global ICrmCompensator_BeginPrepare 4 #comfunc global ICrmCompensator_PrepareRecord 5 int,sptr #comfunc global ICrmCompensator_EndPrepare 6 sptr #comfunc global ICrmCompensator_BeginCommit 7 int #comfunc global ICrmCompensator_CommitRecord 8 int,sptr #comfunc global ICrmCompensator_EndCommit 9 #comfunc global ICrmCompensator_BeginAbort 10 int #comfunc global ICrmCompensator_AbortRecord 11 int,sptr #comfunc global ICrmCompensator_EndAbort 12 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。