Bagikan melalui


Mendaftarkan Sumber Daya sebagai Peserta dalam Transaksi

Setiap sumber daya yang berpartisipasi dalam transaksi dikelola oleh manajer sumber daya, yang tindakannya dikoordinasikan oleh manajer transaksi. Koordinasi dilakukan melalui notifikasi yang diberikan kepada pelanggan yang telah melakukan transaksi melalui pengelola transaksi.

Topik ini mencakup bagaimana sumber daya (atau beberapa sumber daya) dapat didaftarkan dalam suatu transaksi, serta berbagai jenis pendaftaran. Topik Melakukan Transaksi dalam Fase Tunggal dan Multi-Fase mencakup bagaimana komitmen transaksi dapat dikoordinasikan di antara sumber daya yang terdaftar.

Mendaftar Sumber Daya dalam Transaksi

Agar sumber daya berpartisipasi dalam transaksi, itu harus terdaftar dalam transaksi. Kelas Transaction mendefinisikan sekumpulan metode yang namanya dimulai dengan Enlist yang menyediakan fungsionalitas ini. Metode Daftar yang berbeda sesuai dengan berbagai jenis pendaftaran yang mungkin dimiliki oleh manajer sumber daya. Secara khusus, Anda menggunakan metode EnlistVolatile untuk sumber daya yang mudah menguap, dan metode EnlistDurable untuk sumber daya tahan lama. Daya tahan (atau sebaliknya volatilitas) dari manajer sumber daya mengacu pada apakah manajer sumber daya mendukung pemulihan kegagalan. Jika manajer sumber daya mendukung pemulihan kegagalan, data disimpan ke penyimpanan yang tahan lama selama Phase1 (persiapan) sehingga jika manajer sumber daya turun, ini dapat mendaftar kembali dalam transaksi setelah pemulihan dan melakukan tindakan yang tepat berdasarkan pemberitahuan yang diterima dari TM. Secara umum, manajer sumber daya volatil mengelola sumber daya volatil seperti struktur data dalam memori (misalnya, hashtable yang ditransaksikan dalam memori), dan manajer sumber daya tahan lama mengelola sumber daya yang memiliki penyimpanan cadangan yang lebih persisten (misalnya, database yang penyimpanan cadangannya adalah disk).

Untuk mempermudah, setelah memutuskan apakah akan menggunakan metode EnlistDurable atau EnlistVolatile berdasarkan dukungan daya tahan sumber daya Anda, Anda harus meminta sumber daya Anda untuk berpartisipasi dalam Two Phase Commit (2PC) dengan menerapkan antarmuka IEnlistmentNotification untuk manajer sumber daya Anda. Untuk informasi lebih lanjut tentang 2PC, lihat Melakukan Transaksi dalam Fase Tunggal dan Multi Fase.

Satu peserta dapat mendaftar untuk lebih dari satu protokol ini dengan memanggil EnlistDurable dan EnlistVolatile beberapa kali.

Durable Enlistment

Metode EnlistDurable digunakan untuk meminta pengelola sumber daya untuk berpartisipasi dalam transaksi sebagai sumber daya yang tahan lama. Diharapkan jika pengelola sumber daya tahan lama dijatuhkan di tengah transaksi, pemulihan dapat dilakukan setelah dibawa kembali online dengan mendaftar ulang (menggunakan metode Reenlist) di semua transaksi di mana ia menjadi peserta dan melakukan tidak menyelesaikan fase 2, dan memanggil RecoveryComplete setelah proses pemulihan selesai. Untuk informasi selengkapnya tentang pemulihan, lihat Melakukan Pemulihan.

Semua metode EnlistDurable mengambil objek Guid sebagai parameter pertamanya. Guid digunakan oleh manajer transaksi untuk menghubungkan pendaftaran yang tahan lama dengan manajer sumber daya tertentu. Oleh karena itu, sangat penting bahwa pengelola sumber daya secara konsisten menggunakan Guid yang sama untuk mengidentifikasi dirinya bahkan di antara pengelola sumber daya yang berbeda saat memulai ulang, jika tidak, pemulihan dapat gagal.

Parameter kedua dari metode EnlistDurable adalah referensi ke objek yang diterapkan oleh pengelola sumber daya untuk menerima pemberitahuan transaksi. Kelebihan beban yang Anda gunakan memberi tahu manajer transaksi apakah manajer sumber daya Anda mendukung pengoptimalan Single Phase Commit (SPC). Sebagian besar waktu Anda akan mengimplementasikan antarmuka IEnlistmentNotification untuk mengambil bagian dalam Two-Phase Commit (2PC). Namun, jika Anda ingin mengoptimalkan proses penerapan, Anda dapat mempertimbangkan untuk menerapkan antarmuka ISinglePhaseNotification untuk SPC. Untuk informasi lebih lanjut tentang SPC, lihat Melakukan Transaksi dalam Fase Tunggal dan Multi Fase dan Pengoptimalan menggunakan Komitmen Satu Fase dan Pemberitahuan Fase Tunggal yang Dapat Dipromosikan.

Parameter ketiga adalah enumerasi EnlistmentOptions, yang nilainya dapat berupa None atau EnlistDuringPrepareRequired. Jika nilainya diatur ke EnlistDuringPrepareRequired, pendaftaran dapat meminta manajer sumber daya tambahan setelah menerima pemberitahuan Siapkan dari manajer transaksi. Namun, Anda harus menyadari bahwa jenis pendaftaran ini tidak memenuhi syarat untuk pengoptimalan Single Phase Commit.

Volatile Enlistment

Peserta yang mengelola sumber daya yang tidak stabil seperti cache harus mendaftar menggunakan metode EnlistVolatile. Objek tersebut mungkin tidak dapat memperoleh hasil transaksi atau memulihkan status transaksi apa pun yang mereka ikuti setelah kegagalan sistem.

Seperti yang dinyatakan sebelumnya, manajer sumber daya akan membuat pendaftaran yang tidak stabil jika mengelola sumber daya yang tidak stabil di dalam memori. Salah satu manfaat menggunakan EnlistVolatile adalah tidak memaksa eskalasi transaksi yang tidak perlu. Untuk informasi selengkapnya tentang eskalasi transaksi, lihat topik Eskalasi Manajemen Transaksi. Volatilitas pendaftaran menyiratkan perbedaan dalam cara pendaftaran ditangani oleh manajer transaksi, serta apa yang diharapkan dari manajer sumber daya oleh manajer transaksi. Ini karena manajer sumber daya yang tidak stabil tidak melakukan pemulihan. Metode EnlistVolatile tidak menggunakan parameter Guid, karena pengelola sumber daya yang tidak stabil tidak melakukan pemulihan dan tidak akan memanggil metode Reenlist yang memerlukan Guid.

Seperti halnya durable enlistment, metode kelebihan beban mana pun yang Anda gunakan untuk mendaftar menunjukkan kepada manajer transaksi apakah manajer sumber daya Anda mendukung pengoptimalan Single Phase Commit. Karena manajer sumber daya tidak stabil tidak dapat melakukan pemulihan, tidak ada informasi pemulihan yang ditulis untuk volatile enlistment selama fase Persiapan. Oleh karena itu, memanggil metode RecoveryInformation menghasilkan InvalidOperationException.

Contoh berikut menunjukkan cara mendaftarkan objek tersebut sebagai peserta dalam transaksi menggunakan metode EnlistVolatile.

static void Main(string[] args)
{
    try
    {
        using (TransactionScope scope = new TransactionScope())
        {

            //Create an enlistment object
            myEnlistmentClass myEnlistment = new myEnlistmentClass();

            //Enlist on the current transaction with the enlistment object
            Transaction.Current.EnlistVolatile(myEnlistment, EnlistmentOptions.None);

            //Perform transactional work here.

            //Call complete on the TransactionScope based on console input
                            ConsoleKeyInfo c;
            while(true)
                            {
                Console.Write("Complete the transaction scope? [Y|N] ");
                c = Console.ReadKey();
                Console.WriteLine();

                                    if ((c.KeyChar == 'Y') || (c.KeyChar == 'y'))
                {
                    scope.Complete();
                    break;
                }
                else if ((c.KeyChar == 'N') || (c.KeyChar == 'n'))
                {
                    break;
                }
            }
        }
    }
    catch (System.Transactions.TransactionException ex)
    {
        Console.WriteLine(ex);
    }
    catch
    {
        Console.WriteLine("Cannot complete transaction");
        throw;
    }
}

class myEnlistmentClass : IEnlistmentNotification
{
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        Console.WriteLine("Prepare notification received");

        //Perform transactional work

        //If work finished correctly, reply prepared
        preparingEnlistment.Prepared();

        // otherwise, do a ForceRollback
        preparingEnlistment.ForceRollback();
    }

    public void Commit(Enlistment enlistment)
    {
        Console.WriteLine("Commit notification received");

        //Do any work necessary when commit notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void Rollback(Enlistment enlistment)
    {
        Console.WriteLine("Rollback notification received");

        //Do any work necessary when rollback notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void InDoubt(Enlistment enlistment)
    {
        Console.WriteLine("In doubt notification received");

        //Do any work necessary when in doubt notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }
}
    Public Shared Sub Main()
        Try
            Using scope As TransactionScope = New TransactionScope()

                'Create an enlistment object
                Dim myEnlistmentClass As New EnlistmentClass

                'Enlist on the current transaction with the enlistment object
                Transaction.Current.EnlistVolatile(myEnlistmentClass, EnlistmentOptions.None)

                'Perform transactional work here.

                'Call complete on the TransactionScope based on console input
                Dim c As ConsoleKeyInfo
                While (True)
                    Console.Write("Complete the transaction scope? [Y|N] ")
                    c = Console.ReadKey()
                    Console.WriteLine()
                    If (c.KeyChar = "Y") Or (c.KeyChar = "y") Then
                        scope.Complete()
                        Exit While
                    ElseIf ((c.KeyChar = "N") Or (c.KeyChar = "n")) Then
                        Exit While
                    End If
                End While
            End Using
        Catch ex As TransactionException
            Console.WriteLine(ex)
        Catch
            Console.WriteLine("Cannot complete transaction")
            Throw
        End Try
    End Sub
End Class

Public Class EnlistmentClass
    Implements IEnlistmentNotification

    Public Sub Prepare(ByVal myPreparingEnlistment As PreparingEnlistment) Implements System.Transactions.IEnlistmentNotification.Prepare
        Console.WriteLine("Prepare notification received")

        'Perform transactional work

        'If work finished correctly, reply with prepared
        myPreparingEnlistment.Prepared()
    End Sub

    Public Sub Commit(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Commit
        Console.WriteLine("Commit notification received")

        'Do any work necessary when commit notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub

    Public Sub Rollback(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Rollback
        Console.WriteLine("Rollback notification received")

        'Do any work necessary when rollback notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub

    Public Sub InDoubt(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.InDoubt
        Console.WriteLine("In doubt notification received")

        'Do any work necessary when in doubt notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub
End Class

Mengoptimalkan Performa

Kelas Transaction juga menyediakan metode EnlistPromotableSinglePhase untuk mendaftarkan Promotable Single Phase Enlistment (PSPE). Ini memungkinkan pengelola sumber daya (RM) yang tahan lama untuk meng-host dan "memiliki" transaksi yang nantinya dapat ditingkatkan untuk dikelola oleh MSDTC jika perlu. Untuk informasi selengkapnya tentang ini, lihat Pengoptimalan menggunakan Single Phase Commit dan Pemberitahuan Promotable Single Phase.

Lihat juga