Procédure de création d'un gestionnaire CRM
Exemple de code
Un gestionnaire CRM (compensating resource manager) est un service fourni par COM+ qui vous permet d'inclure des objets non transactionnels dans des transactions Microsoft Distributed Transaction Coordinator (DTC). Bien que les CRM n'offrent pas les mêmes fonctionnalités qu'un gestionnaire de ressources complet, ils assurent néanmoins l'atomicité transactionnelle (comportement de type tout ou rien) et la durabilité via le journal de récupération.
Créer un gestionnaire CRM
Importez les espaces de noms EnterpriseServices et CompensatingResourceManager.
Imports System.EnterpriseServices Imports System.EnterpriseServices.CompensatingResourceManager
using System.EnterpriseServices; using System.EnterpriseServices.CompensatingResourceManager;
Activez la prise en charge CRM pour l'assembly.
<assembly: ApplicationCrmEnabled>
[assembly: ApplicationCrmEnabled]
Définissez une classe de travail CRM qui dérive de la classe ServicedComponent. Par exemple, le code suivant montre une classe
CRMWorker
qui dérive directement de la classe ServicedComponent.<Transaction> Public Class CRMWorker Inherits Servicedcomponent End Class
[Transaction] public class CRMWorker:ServicedComponent { }
Implémentez une méthode publique qui crée un objet Clerk et valide ou annule la transaction. Cette méthode doit mettre à jour le journal du gestionnaire CRM en utilisant l'objet Clerk. Par exemple, le code suivant montre une méthode
CRMMethod
qui met à jour le journal du gestionnaire CRM et valide ou annule la transaction.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(); }
Définissez une classe qui dérive de la classe Compensation.
JustInTimeActivation() Public Class CRMCompensator Inherits Compensator End Class
[JustInTimeActivation] public class CRMCompensator:Compensator { }
![]() |
---|
Vous devez appliquer l'attribut |
Remplacez les membres
BeginPrepare
,PrepareRecord
,EndPrepare
,BeginCommit
,CommitRecord
,EndCommit
,BeginAbort
,AbortRecord
etEndAbort
de la classe Compensator.Créez une application cliente pour tester les composants CRM Worker et Compensator.
Importez les noms requis, tels que System.EnterpriseServices et l'espace de noms qui implemente les classes CRM Worker et 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;
Définissez une classe et implémentez la méthode Main pour créer une instance de la classe CRM Worker, puis appelez cette méthode pour créer l'objet CRM Clerk. Par exemple, le code suivant crée un objet de type
CRMWorker
et appelle la méthodeCRMMethod
pour créer l'objet 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; } }
Générez une clé forte et compilez l'exemple de code suivant.
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
Exemple
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.
}
}
}
Voir aussi
Référence
System.EnterpriseServices Namespace
Concepts
Résumé des services COM+ disponibles
Copyright ©2007 par Microsoft Corporation. Tous droits réservés.