(0) exportieren Drucken
Alle erweitern

Verfahrensweise: Erstellen eines kompensierenden Ressourcen-Managers (CRM)

Codebeispiel

Ein kompensierender Ressourcen-Manager (Compensating Resource Manager, CRM) ist ein von COM+ bereitgestellter Dienst, mit dem Sie nicht transaktionale Objekte in DTC-Transaktionen (Microsoft Distributed Transaction Coordinator) aufnehmen können. Obwohl CRMs nicht über die Fähigkeiten eines vollständigen Ressourcen-Managers verfügen, kann durch sie mithilfe des Wiederherstellungsprotokolls die Unteilbarkeit (Verhalten nach dem Prinzip "alles oder nichts") und Dauerhaftigkeit von Transaktionen gewährleistet werden.

So erstellen Sie einen kompensierenden Ressourcen-Manager

  1. Importieren Sie die Namespaces "EnterpriseServices" und "CompensatingResourceManager".

    Imports System.EnterpriseServices
    Imports System.EnterpriseServices.CompensatingResourceManager
    

    using System.EnterpriseServices;
    using System.EnterpriseServices.CompensatingResourceManager;
    
    
  2. Aktivieren Sie die CRM-Unterstützung für die Assembly.

    <assembly: ApplicationCrmEnabled>
    
    

    [assembly: ApplicationCrmEnabled]
    
    
    
  3. Definieren Sie eine CRM-Workerklasse, die von der ServicedComponent-Klasse abgeleitet wird. Der folgende Code zeigt beispielsweise eine Klasse CRMWorker , die direkt von der ServicedComponent-Klasse abgeleitet wird.

    <Transaction> Public Class CRMWorker
          Inherits Servicedcomponent
                
    End Class
    

    [Transaction]
    public class CRMWorker:ServicedComponent
    {
    }
    
  4. Implementieren Sie eine öffentliche Methode, die ein Clerk-Objekt erstellt und den Commit der Transaktion durchführt oder sie abbricht. Die Methode muss das CRM-Protokoll mithilfe des Clerk-Objekts aktualisieren. Der folgende Code beispielsweise zeigt eine Methode CRMMethod, die das CRM-Protokoll aktualisiert und den Commit der Transaktion durchführt oder sie abbricht.

    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();
          }
    
    
  5. Definieren Sie eine Klasse, die von der Compensator-Klasse abgeleitet wird.

    JustInTimeActivation()
    Public Class CRMCompensator
            Inherits Compensator
    End Class
    

    [JustInTimeActivation]
    public class CRMCompensator:Compensator
    {
    }
    
    
NoteHinweis:

Sie müssen das JustInTimeActivation-Attribut auf den Kompensator anwenden. Andernfalls wird der Abbruch zweimal aufgerufen.

  1. Setzen Sie die BeginPrepare-, PrepareRecord-, EndPrepare-, BeginCommit-, CommitRecord-, EndCommit-, BeginAbort-, AbortRecord- und EndAbort-Member der Compensator-Klasse außer Kraft.

  2. Erstellen Sie eine Clientanwendung zum Testen der CRM-Worker- und -Kompensatorkomponenten.

    1. Importieren Sie die erforderlichen Namen, wie z. B. System.EnterpriseServices und den Namespace, der die CRM-Worker- und -Kompensatorklassen implementiert.

      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;
      
      
    2. Definieren Sie eine Klasse, und implementieren Sie die Main-Methode, um eine Instanz der CRM-Workerklasse, und rufen Sie die Methode auf, die das CRM-Clerk-Objekt erstellt. Der folgende Code erstellt beispielsweise ein Objekt vom Typ CRMWorker und ruft die Methode CRMMethod auf, um das CRM-Clerk-Objekt zu erstellen.

      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;   
          }
      }
      
      
  3. Generieren Sie einen starken Schlüssel, und kompilieren Sie folgendes Beispiel.

    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
    
    

Beispiel

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.
            }
      
      }

}

Siehe auch

Footer image



Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.

Community-Beiträge

HINZUFÜGEN
Microsoft führt eine Onlineumfrage durch, um Ihre Meinung zur MSDN-Website zu erfahren. Wenn Sie sich zur Teilnahme entscheiden, wird Ihnen die Onlineumfrage angezeigt, sobald Sie die MSDN-Website verlassen.

Möchten Sie an der Umfrage teilnehmen?
Anzeigen:
© 2014 Microsoft