方法 :Compensating Resource Manager (CRM) を作成する
コード例
CRM (Compensating Resource Manager) とは、非トランザクション オブジェクトを Microsoft 分散トランザクション コーディネータ (DTC: Distributed Transaction Coordinator) トランザクションに組み込むことができるようにする COM+ のサービスです。CRM は完全なリソース マネージャの機能を備えていませんが、トランザクションの最小性 (all-or-nothing の動作) と、復元ログを通じての永続性を提供します。
Compensating Resource Manager 作成するには
EnterpriseServices および CompensatingResourceManager 名前空間をインポートします。
Imports System.EnterpriseServices Imports System.EnterpriseServices.CompensatingResourceManager
using System.EnterpriseServices; using System.EnterpriseServices.CompensatingResourceManager;
CRM のアセンブリ サポートを有効にします。
<assembly: ApplicationCrmEnabled>
[assembly: ApplicationCrmEnabled]
ServicedComponent クラスから派生する CRM Worker クラスを定義します。たとえば、次のコードは、ServicedComponent から直接派生する
CRMWorker
クラスを示しています。<Transaction> Public Class CRMWorker Inherits Servicedcomponent End Class
[Transaction] public class CRMWorker:ServicedComponent { }
Clerk オブジェクトを作成するパブリック メソッドを実装し、トランザクションをコミットまたは中止します。このメソッドは、Clerk オブジェクトを使用して CRM ログを更新する必要があります。たとえば、次のコードは、CRM ログを更新してトランザクションをコミットまたは中止するメソッド
CRMMethod
を示しています。Public Sub CRMMethod(filename As String, bCommit As Boolean) ' Create the clerk object. Dim myclerk As Clerk=New Clerk(GetType(CRMCompensator), _ "CRMCompensator", CompensatorOptions.AllPhases) myclerk.WriteLogRecord(filename) myclerk.ForceLog() If bCommit=true Then ContextUtil.SetComplete() Else ContextUtil.SetAbort() End If End Sub
public void CRMMethod(string fileName, bool bCommit) { // Create clerk object. Clerk clerk = new Clerk(typeof(CRMCompensator), "CRMCompensator", CompensatorOptions.AllPhases); clerk.WriteLogRecord(fileName); clerk.ForceLog(); if (bCommit) ContextUtil.SetComplete(); else ContextUtil.SetAbort(); }
Compensation クラスから派生するクラスを定義します。
JustInTimeActivation() Public Class CRMCompensator Inherits Compensator End Class
[JustInTimeActivation] public class CRMCompensator:Compensator { }
メモ : |
---|
|
Compensator クラスのメンバである
BeginPrepare
、PrepareRecord
、EndPrepare
、BeginCommit
、CommitRecord
、EndCommit
、BeginAbort
、AbortRecord
、およびEndAbort
をオーバーライドします。クライアント アプリケーションを作成して、CRM Worker コンポーネントおよび Compensator コンポーネントをテストします。
System.EnterpriseServices などの必須名、および CRM Worker クラスおよび Compensator クラスを実装する名前空間をインポートします。
Imports System Imports System.IO Imports System.EnterpriseServices Imports CrmServer Imports System.Runtime.InteropServices
using System; using System.IO; using System.EnterpriseServices; using CrmServer; using System.Runtime.InteropServices;
クラスを定義し Main メソッドを実装して、CRM Worker クラスのインスタンスを作成します。さらに、CRM Clerk オブジェクトを作成するメソッドを呼び出します。たとえば、次のコードでは、
CRMWorker
タイプのオブジェクトを作成しCRMMethod
メソッドを呼び出して、CRM Clerk オブジェクトを作成します。Public Class CRM Public Shared Sub Main() dim logfilename As String = "crm.log" Console.WriteLine("Creating a managed CRM worker"+ _ "object...") dim crmworker As CRMWorker = new CRMWorker() Console.WriteLine("Demonstrating a worker commit...") crmworker.CRMMethod(logfilename, True) Console.WriteLine("Demonstrating a worker abort...") crmworker.CRMMethod(logfilename, False) Console.WriteLine("DONE!") End Sub End Class
class CRM { public static int Main() { string logfilename = "crm.log"; Console.WriteLine("Creating a managed CRM worker object..."); CRMWorker crmworker = new CRMWorker(); Console.WriteLine("Demonstrating a worker commit..."); crmworker.CRMMethod(logfilename, true); Console.WriteLine("Demonstrating a worker abort..."); crmworker.CRMMethod(logfilename, false); Console.WriteLine("DONE!"); return 0; } }
強力なキーを生成して、次の例をコンパイルします。
sn –k crm.key vbc /t:library /r:System.EnterpriseServices.dll crm.vb vbc /r:crm.dll /r:System.EnterpriseServices.dll crmclient.vb
sn –k crm.key csc /t:library /r:System.EnterpriseServices.dll crm.cs csc /r:crm.dll crmclient.cs
例
Imports System
Imports System.IO
Imports System.Reflection
Imports System.EnterpriseServices
Imports System.EnterpriseServices.CompensatingResourceManager
<assembly: ApplicationActivation(ActivationOption.Server)>
<assembly: ApplicationCrmEnabled>
<assembly: AssemblyKeyFile("crm.key")>
Namespace CrmServer
' Create a Worker class.
<Transaction> Public Class CRMWorker
Inherits Servicedcomponent
Public Sub CRMMethod(filename As String, bCommit As Boolean)
' Create the clerk object.
Dim myclerk As Clerk=New Clerk(GetType(CRMCompensator), _
"CRMCompensator", CompensatorOptions.AllPhases)
myclerk.WriteLogRecord(filename)
myclerk.ForceLog()
If bCommit=true Then
ContextUtil.SetComplete()
Else
ContextUtil.SetAbort()
End If
End Sub
End Class
' Create a class derived from the Compensator class.
JustInTimeActivation()
Public Class CRMCompensator
Inherits Compensator
Dim bBeginPrepareCalled As Boolean = False
Dim bPrepareRecordCalled As Boolean = False
Dim bBeginCommitCalled As Boolean = False
Dim bCommitRecordCalled As Boolean = False
Dim bBeginAbortCalled As Boolean = False
Dim bAbortRecordCalled As Boolean = False
Dim _filename as String
Public Overrides Sub BeginPrepare()
bBeginPrepareCalled = True
End Sub
Public Overrides Function PrepareRecord(rec As LogRecord) _
As Boolean
dim o as Object = rec.Record
_fileName = o.ToString()
bPrepareRecordCalled = True
Return False
End Function
Public Overrides Function EndPrepare() As Boolean
if not bBeginPrepareCalled then Return False
if not bPrepareRecordCalled then Return False
if _fileName="" then Return False
' This is a Prepare Phase success.
Return True
End Function
Public Overrides Sub BeginCommit(fRecovery As Boolean)
bBeginCommitCalled = True
End Sub
Public Overrides Function CommitRecord(rec As LogRecord) _
As Boolean
bCommitRecordCalled = True
Return True
End Function
Public Overrides Sub EndCommit()
if not bBeginCommitCalled then Return
if not bCommitRecordCalled then Return
if _fileName="" then Return
' This is a Commit Phase success.
End Sub
Public Overrides Sub BeginAbort(fRecovery As Boolean)
bBeginAbortCalled = True
End Sub
Public Overrides Function AbortRecord(rec As LogRecord) _
As Boolean
bAbortRecordCalled = True
dim o as Object = rec.Record
_fileName = o.ToString()
Return True
End Function
Public Overrides Sub EndAbort()
if not bBeginAbortCalled then Return
if not bAbortRecordCalled then Return
if _fileName="" then Return
' This is an Abort Phase success.
End Sub
End Class
End Namespace
using System;
using System.IO;
using System.Reflection;
using System.EnterpriseServices;
using System.EnterpriseServices.CompensatingResourceManager;
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationCrmEnabled]
[assembly: AssemblyKeyFile("crm.key")]
namespace CrmServer
{
[Transaction]
// Create a Worker class.
public class CRMWorker:ServicedComponent
{
public void CRMMethod(string fileName, bool bCommit)
{
// Create clerk object.
Clerk clerk = new Clerk(typeof(CRMCompensator),
"CRMCompensator", CompensatorOptions.AllPhases);
clerk.WriteLogRecord(fileName);
clerk.ForceLog();
if (bCommit)
ContextUtil.SetComplete();
else
ContextUtil.SetAbort();
}
}
// Create class derived from Compensator class.
[JustInTimeActivation]
public class CRMCompensator:Compensator
{
bool bBeginPrepareCalled = false;
bool bPrepareRecordCalled = false;
bool bBeginCommitCalled = false;
bool bCommitRecordCalled = false;
bool bBeginAbortCalled = false;
bool bAbortRecordCalled = false;
String _fileName;
public override void BeginPrepare()
{
bBeginPrepareCalled = true;
}
public override bool PrepareRecord(LogRecord rec)
{
Object o = rec.Record;
_fileName = o.ToString();
bPrepareRecordCalled = true;
return false;
}
public override bool EndPrepare()
{
if (!bBeginPrepareCalled)
{return false;}
if (!bPrepareRecordCalled)
{return false;}
if (_fileName==null)
{return false;}
// This is a Prepare Phase success.
return true;
}
public override void BeginCommit(bool fRecovery)
{
bBeginCommitCalled = true;
}
public override bool CommitRecord(LogRecord rec)
{
bCommitRecordCalled = true;
return true;
}
public override void EndCommit()
{
if (!bBeginCommitCalled)
{return;}
if (!bCommitRecordCalled)
{return;}
if (_fileName==null)
{return;}
// This is a Commit Phase success.
}
public override void BeginAbort(bool fRecovery)
{
bBeginAbortCalled = true;
}
public override bool AbortRecord(LogRecord rec)
{
bAbortRecordCalled = true;
Object o = rec.Record;
_fileName = o.ToString();
return true;
}
public override void EndAbort()
{
if (!bBeginAbortCalled)
{return;}
if (!bAbortRecordCalled)
{return;}
if (_fileName==null)
{return;}
// This is an Abort Phase success.
}
}
}
関連項目
参照
System.EnterpriseServices Namespace
概念
Copyright © 2007 by Microsoft Corporation.All rights reserved.