Compensator 類別

定義

表示所有 Compensating Resource Manager (CRM) 補償器的基底類別。

public ref class Compensator : System::EnterpriseServices::ServicedComponent
public class Compensator : System.EnterpriseServices.ServicedComponent
type Compensator = class
    inherit ServicedComponent
Public Class Compensator
Inherits ServicedComponent
繼承

範例

下列程式代碼範例示範如何使用這個類別。

// A CRM Compensator
public ref class AccountCompensator : public Compensator
{
private:
    bool receivedPrepareRecord;

public:
    AccountCompensator()
    {
        receivedPrepareRecord = false;
    } 

public:
    virtual void BeginPrepare() override 
    {
        // nothing to do
    }

public:
    virtual bool PrepareRecord(LogRecord^ log) override 
    {

        // Check the validity of the record.
        if (log == nullptr)
        {
            return false;
        }
        array<Object^>^ record = dynamic_cast<array<Object^>^>(log->Record);
        if (record == nullptr)
        {
            return false;
        }
        if (record->Length != 2)
        {
            return false;
        }

        // The record is valid.
        receivedPrepareRecord = true;
        return true;              
    }

public:
    virtual bool EndPrepare() override
    {
        // Allow the transaction to proceed onlyif we have received a prepare
        // record.
        if (receivedPrepareRecord)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

public:
    virtual void BeginCommit(bool commit) override
    {
        // nothing to do
    }

public:
    virtual bool CommitRecord(LogRecord^ log) override
    {
        // nothing to do
        return(false);
    }

public:
    virtual void EndCommit() override
    {
        // nothing to do
    }

public:
    virtual void BeginAbort(bool abort) override
    {
        // nothing to do
    }

public:
    virtual bool AbortRecord(LogRecord^ log) override
    {

        // Check the validity of the record.
        if (log == nullptr)
        {
            return true;
        }
        array<Object^>^ record = dynamic_cast<array<Object^>^>(log->Record);
        if (record == nullptr)
        {
            return true;
        }
        if (record->Length != 2)
        {
            return true;
        }

        // Extract old account data from the record.
        String^ filename = (String^) record[0];
        int balance = (int) record[1];

        // Restore the old state of the account.
        WriteAccountBalance(filename, balance);

        return false;
    }

public:
    virtual void EndAbort() override
    {
        // nothing to do
    }    

};
// A CRM Compensator
public class AccountCompensator : Compensator
{

    private bool receivedPrepareRecord = false;

    public override void BeginPrepare ()
    {
        // nothing to do
    }

    public override bool PrepareRecord (LogRecord log)
    {

        // Check the validity of the record.
        if (log == null) return(true);
        Object[] record = log.Record as Object[];
        if (record == null) return(true);
        if (record.Length != 2) return(true);

        // The record is valid.
        receivedPrepareRecord = true;
        return(false);
    }

    public override bool EndPrepare ()
    {
        // Allow the transaction to proceed onlyif we have received a prepare record.
        if (receivedPrepareRecord)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }

    public override void BeginCommit (bool commit)
    {
        // nothing to do
    }

    public override bool CommitRecord (LogRecord log)
    {
        // nothing to do
        return(false);
    }

    public override void EndCommit ()
    {
        // nothing to do
    }

    public override void BeginAbort (bool abort)
    {
        // nothing to do
    }

    public override bool AbortRecord (LogRecord log)
    {

        // Check the validity of the record.
        if (log == null) return(true);
        Object[] record = log.Record as Object[];
        if (record == null) return(true);
        if (record.Length != 2) return(true);

        // Extract old account data from the record.
        string filename = (string) record[0];
        int balance = (int) record[1];

        // Restore the old state of the account.
        AccountManager.WriteAccountBalance(filename, balance);

        return(false);
    }

    public override void EndAbort ()
    {
        // nothing to do
    }
}
' A CRM Compensator

Public Class AccountCompensator
    Inherits Compensator
    
    Private receivedPrepareRecord As Boolean = False
    
    
    Public Overrides Sub BeginPrepare() 
    
    End Sub
    
    ' nothing to do
    Public Overrides Function PrepareRecord(ByVal log As LogRecord) As Boolean 
        
        ' Check the validity of the record.
        If log Is Nothing Then
            Return True
        End If
        Dim record As [Object]() = log.Record
        
        If record Is Nothing Then
            Return True
        End If
        If record.Length <> 2 Then
            Return True
        End If 
        ' The record is valid.
        receivedPrepareRecord = True
        Return False
    
    End Function 'PrepareRecord
    
    Public Overrides Function EndPrepare() As Boolean 
        ' Allow the transaction to proceed onlyif we have received a prepare record.
        If receivedPrepareRecord Then
            Return True
        Else
            Return False
        End If
    
    End Function 'EndPrepare
    
    Public Overrides Sub BeginCommit(ByVal commit As Boolean) 
    
    End Sub
    
    ' nothing to do
    Public Overrides Function CommitRecord(ByVal log As LogRecord) As Boolean 
        ' nothing to do
        Return False
    
    End Function 'CommitRecord
    
    Public Overrides Sub EndCommit() 
    
    End Sub
    
    ' nothing to do
    Public Overrides Sub BeginAbort(ByVal abort As Boolean) 
    
    End Sub
    
    ' nothing to do
    Public Overrides Function AbortRecord(ByVal log As LogRecord) As Boolean 
        
        ' Check the validity of the record.
        If log Is Nothing Then
            Return True
        End If
        Dim record As [Object]() = log.Record
        
        If record Is Nothing Then
            Return True
        End If
        If record.Length <> 2 Then
            Return True
        End If 
        ' Extract old account data from the record.
        Dim filename As String = CStr(record(0))
        Dim balance As Integer = Fix(record(1))
        
        ' Restore the old state of the account.
        AccountManager.WriteAccountBalance(filename, balance)
        
        Return False
    
    End Function 'AbortRecord
    
    Public Overrides Sub EndAbort() 
    
    End Sub
End Class

下列背景工作類別會使用此補償器。

// A CRM Worker
[Transaction]
public ref class Account : public ServicedComponent
{

    // A data member for the account file name.
private:
    String^ filenameValue;

public:
    property String^ Filename
    {
        String^ get()
        {
            return filenameValue;
        }
        void set( String^ value )
        {
            filenameValue = value;
        }
    }

    // A boolean data member that determines whether to commit or abort the 
    // transaction.
private:
    bool allowCommitValue;

public:
    property bool AllowCommit
    {
        bool get()
        {
            return allowCommitValue;
        }
        void set( bool value )
        {
            allowCommitValue = value;
        }
    }

    // Debit the account, 
public:
    void DebitAccount(int amount)
    {

        // Create a new clerk using the AccountCompensator class.
        Clerk^ clerk = gcnew Clerk(AccountCompensator::typeid,
            "An account transaction compensator", CompensatorOptions::AllPhases);

        // Create a record of previous account status, and deliver it to the
        // clerk.
        int balance = ReadAccountBalance(Filename);

        array<Object^>^ record = gcnew array<Object^>(2);
        record[0] = Filename;
        record[1] = balance;

        clerk->WriteLogRecord(record);
        clerk->ForceLog();

        // Perform the transaction
        balance -= amount;

        Console::WriteLine("{0}: {1}", Filename, balance);

        WriteAccountBalance(Filename, balance);

        // Commit or abort the transaction 
        if (AllowCommit)
        {
            ContextUtil::SetComplete();
        }
        else
        {
            ContextUtil::SetAbort();
        }

    }

};
// A CRM Worker
[Transaction]
public class Account : ServicedComponent
{

    // A data member for the account file name.
    private string filename;

    public string Filename
    {
        get
        {
            return(filename);
        }
        set
        {
            filename = value;
        }
    }

    // A boolean data member that determines whether to commit or abort the transaction.
    private bool commit;

    public bool AllowCommit
    {
        get
        {
            return(commit);
        }
        set
        {
            commit = value;
        }
    }

    // Debit the account,
    public void DebitAccount (int ammount)
    {

        // Create a new clerk using the AccountCompensator class.
        Clerk clerk = new Clerk(typeof(AccountCompensator),
          "An account transaction compensator", CompensatorOptions.AllPhases);

        // Create a record of previous account status, and deliver it to the clerk.
        int balance = AccountManager.ReadAccountBalance(filename);

    Object[] record = new Object[2];
    record[0] = filename;
        record[1] = balance;

        clerk.WriteLogRecord(record);
        clerk.ForceLog();

        // Perform the transaction
        balance -= ammount;
        AccountManager.WriteAccountBalance(filename, balance);

        // Commit or abort the transaction
        if (commit)
        {
            ContextUtil.SetComplete();
        }
        else
        {
            ContextUtil.SetAbort();
        }
    }
}
' A CRM Worker
<Transaction()>  _
Public Class Account
    Inherits ServicedComponent
    
    ' A data member for the account file name.
    Private filename As String
    
    
    Public Property Filenam() As String
        Get
            Return Filename
        End Get
        Set(ByVal value As String)
            filename = Value
        End Set
    End Property
    
    
    ' A boolean data member that determines whether to commit or abort the transaction.
    Private commit As Boolean
    
    
    Public Property AllowCommit() As Boolean 
        Get
            Return commit
        End Get
        Set
            commit = value
        End Set
    End Property
    
    
    
    
    ' Debit the account, 
    Public Sub DebitAccount(ByVal ammount As Integer) 
        
        ' Create a new clerk using the AccountCompensator class.
        Dim clerk As New Clerk(GetType(AccountCompensator), "An account transaction compensator", CompensatorOptions.AllPhases)
        ' Create a record of previous account status, and deliver it to the clerk.
        Dim balance As Integer = AccountManager.ReadAccountBalance(Filenam)
        
        Dim record(1) As [Object]
        record(0) = filename
        record(1) = balance
        
        clerk.WriteLogRecord(record)
        clerk.ForceLog()
        ' Perform the transaction
        balance -= ammount
        AccountManager.WriteAccountBalance(filename, balance)
        
        ' Commit or abort the transaction 
        If commit Then
            ContextUtil.SetComplete()
        Else
            ContextUtil.SetAbort()
        End If
    End Sub
    
End Class

下列程式代碼範例示範執行此補償器和背景工作的用戶端。

#using "System.EnterpriseServices.dll"

using namespace System;

[assembly: System::Reflection::AssemblyKeyFile("CrmServer.key")];

int main ()
{

    // Create a new account object. The object is created in a COM+ server application.
    Account^ account = gcnew Account();

    // Transactionally debit the account.
    try
    {
        account->Filename = System::IO::Path::GetFullPath("JohnDoe");
        account->AllowCommit = true;
        account->DebitAccount(3);
    }
    finally
    {
        delete account;
    }

}
using System;

public class CrmClient
{

    public static void Main ()
    {

        // Create a new account object. The object is created in a COM+ server application.
        Account account = new Account();

        // Transactionally debit the account.
        try
        {
            account.Filename = System.IO.Path.GetFullPath("JohnDoe");
            account.AllowCommit = true;
            account.DebitAccount(3);
        }
        finally
        {
            account.Dispose();
        }
    }
}
Public Class CrmClient
    
    
    Public Shared Sub Main() 
        
        ' Create a new account object. The object is created in a COM+ server application.
        Dim account As New Account()
        
        ' Transactionally debit the account.
        Try
            account.Filenam = System.IO.Path.GetFullPath("JohnDoe")
            account.AllowCommit = True
            account.DebitAccount(3)
        Finally
            account.Dispose()
        End Try
    
    End Sub
End Class

備註

用戶應該從這個物件擴充,以撰寫自定義交易補償器。

補償器必須一律具有公用建構函式;否則,復原引擎無法建立它。

如需詳細資訊,請參閱如何:Create 補償 Resource Manager (CRM)

建構函式

Compensator()

初始化 Compensator 類別的新執行個體。

屬性

Clerk

取得表示 Compensating Resource Manager (CRM) Clerk 物件的值。

方法

AbortRecord(LogRecord)

在中止階段期間傳送記錄檔資料錄至 Compensating Resource Manager (CRM) 補償器。

Activate()

從集區建立或配置物件時由基礎結構所呼叫。 覆寫這個方法來加入自訂初始化程式碼至物件。

(繼承來源 ServicedComponent)
BeginAbort(Boolean)

告知 Compensating Resource Manager (CRM) 補償器,關於交易完成的中止階段和資料錄即將傳送。

BeginCommit(Boolean)

告知 Compensating Resource Manager (CRM) 補償器,關於交易完成的認可階段和資料錄即將傳送。

BeginPrepare()

告知 Compensating Resource Manager (CRM) 補償器,關於交易完成的準備階段和資料錄即將傳送。

CanBePooled()

這個方法在物件放回集區內之前為基礎結構所呼叫。 覆寫這個方法來表決物件是否要放回到集區內。

(繼承來源 ServicedComponent)
CommitRecord(LogRecord)

在認可階段依轉寄順序傳送記錄檔資料錄。

Construct(String)

剛好在傳入建構函式字串並呼叫建構函式之後由基礎結構所呼叫。 覆寫這個方法來利用建構字串值。

(繼承來源 ServicedComponent)
CreateObjRef(Type)

建立包含所有相關資訊的物件,這些資訊是產生用來與遠端物件通訊的所需 Proxy。

(繼承來源 MarshalByRefObject)
Deactivate()

物件即將停用時由基礎結構所呼叫。 在使用 Just-In-Time (JIT) 編譯的程式碼或物件共用時,可覆寫這個方法來加入自訂最終處理程式碼至物件。

(繼承來源 ServicedComponent)
Dispose()

釋放 ServicedComponent 所使用的所有資源。

(繼承來源 ServicedComponent)
Dispose(Boolean)

釋放 ServicedComponent 所使用的 Unmanaged 資源,並選擇性地釋放 Managed 資源。

(繼承來源 ServicedComponent)
EndAbort()

告知 Compensating Resource Manager (CRM) 補償器,它在中止階段期間已經收到所有可用的記錄檔資料錄。

EndCommit()

告知 Compensating Resource Manager (CRM) 補償器,它在認可階段期間已經傳送所有可用的記錄檔資料錄。

EndPrepare()

告知 Compensating Resource Manager (CRM) 補償器,它在準備階段期間已經擁有所有可用的記錄檔資料錄。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetLifetimeService()
已淘汰.

擷取控制這個執行個體存留期 (Lifetime) 原則的目前存留期服務物件。

(繼承來源 MarshalByRefObject)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
InitializeLifetimeService()
已淘汰.

取得存留期服務物件,以控制這個執行個體的存留期原則。

(繼承來源 MarshalByRefObject)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
MemberwiseClone(Boolean)

建立目前 MarshalByRefObject 物件的淺層複本。

(繼承來源 MarshalByRefObject)
PrepareRecord(LogRecord)

在準備階段依轉寄順序傳送記錄檔資料錄。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

明確介面實作

IRemoteDispatch.RemoteDispatchAutoDone(String)

此 API 支援此產品基礎結構,但無法直接用於程式碼之中。

確保在 COM+ 內容中,ServicedComponent 類別物件的 done 位元會在 Remote Method Invocation 之後設為 true

(繼承來源 ServicedComponent)
IRemoteDispatch.RemoteDispatchNotAutoDone(String)

不能確保在 COM+ 內容中,ServicedComponent 類別物件的 done 位元會在 Remote Method Invocation 之後設為 true

(繼承來源 ServicedComponent)
IServicedComponentInfo.GetComponentInfo(Int32, String[])

取得 ServicedComponent 類別執行個體的某些資訊。

(繼承來源 ServicedComponent)

適用於