Bagikan melalui


Alur Transaksi WS

Sampel TransactionFlow menunjukkan penggunaan transaksi yang dikoordinasikan klien dan opsi klien serta server untuk alur transaksi menggunakan protokol Transaksi WS-Atomic atau OleTransactions. Sampel ini didasarkan pada Memulai yang mengimplementasikan layanan kalkulator, tetapi operasi dikaitkan untuk menunjukkan penggunaan TransactionFlowAttribute dengan enumerasi TransactionFlowOption untuk menentukan alur transaksi tingkat apa yang diaktifkan. Dalam cakupan transaksi yang dialirkan, log operasi yang diminta ditulis ke database dan berlanjut sampai transaksi yang dikoordinasikan klien selesai - jika transaksi klien tidak selesai, transaksi Layanan Web memastikan bahwa pembaruan yang sesuai untuk database tidak diterapkan.

Catatan

Prosedur penyiapan dan petunjuk pembuatan untuk sampel ini terdapat di akhir topik ini.

Setelah memulai koneksi ke layanan dan transaksi, klien mengakses beberapa operasi layanan. Kontrak untuk layanan ditentukan sebagai berikut dengan setiap operasi yang menunjukkan pengaturan yang berbeda untuk TransactionFlowOption.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Mandatory)]
    double Add(double n1, double n2);
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    double Subtract(double n1, double n2);
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.NotAllowed)]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
}

Hal ini menentukan operasi dalam urutan pemrosesannya:

  • Permintaan operasi Add harus menyertakan transaksi yang dialirkan.

  • Permintaan operasi Subtract dapat menyertakan transaksi yang dialirkan.

  • Permintaan operasi Multiply tidak boleh menyertakan transaksi yang dialirkan melalui pengaturan NotAllowed eksplisit.

  • Permintaan operasi Divide tidak boleh menyertakan transaksi yang dialirkan melalui penghapusan atribut TransactionFlow.

Untuk mengaktifkan alur transaksi, pengikatan dengan properti <transactionFlow> yang diaktifkan harus digunakan selain atribut operasi yang sesuai. Dalam sampel ini, konfigurasi layanan mengekspos titik akhir TCP dan titik akhir HTTP selain titik akhir Metadata Exchange. Titik akhir TCP dan titik akhir HTTP menggunakan pengikatan berikut, yang keduanya mengaktifkan properti <transactionFlow>.

<bindings>
  <netTcpBinding>
    <binding name="transactionalOleTransactionsTcpBinding"
             transactionFlow="true"
             transactionProtocol="OleTransactions"/>
  </netTcpBinding>
  <wsHttpBinding>
    <binding name="transactionalWsatHttpBinding"
             transactionFlow="true" />
  </wsHttpBinding>
</bindings>

Catatan

NetTcpBinding yang disediakan sistem memungkinkan spesifikasi transactionProtocol sedangkan wsHttpBinding yang disediakan sistem hanya menggunakan protokol WSAtomicTransactionOctober2004 yang lebih dapat dioperasikan. Protokol OleTransactions hanya tersedia untuk digunakan oleh klien Windows Communication Foundation (WCF).

Untuk kelas yang mengimplementasikan antarmuka ICalculator, semua metode dikaitkan dengan properti TransactionScopeRequired yang diatur ke true. Pengaturan ini menyatakan bahwa semua tindakan yang diambil dalam metode terjadi dalam cakupan transaksi. Dalam hal ini, tindakan yang diambil termasuk merekam ke database log. Jika permintaan operasi menyertakan transaksi yang dialirkan maka tindakan terjadi dalam cakupan transaksi masuk atau cakupan transaksi baru dihasilkan secara otomatis.

Catatan

Properti TransactionScopeRequired menentukan perilaku lokal untuk implementasi metode layanan dan tidak menentukan kemampuan atau persyaratan klien untuk mengalirkan transaksi.

// Service class that implements the service contract.
[ServiceBehavior(TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable)]
public class CalculatorService : ICalculator
{
    [OperationBehavior(TransactionScopeRequired = true)]
    public double Add(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Adding {0} to {1}", n1, n2));
        return n1 + n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Subtract(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Subtracting {0} from {1}", n2, n1));
        return n1 - n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Multiply(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Multiplying {0} by {1}", n1, n2));
        return n1 * n2;
    }

    [OperationBehavior(TransactionScopeRequired = true)]
    public double Divide(double n1, double n2)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Dividing {0} by {1}", n1, n2));
        return n1 / n2;
    }

    // Logging method omitted for brevity
}

Pada klien, pengaturan TransactionFlowOption layanan pada operasi tercermin dalam definisi antarmuka ICalculator yang dihasilkan klien. Selain itu, pengaturan properti transactionFlow layanan tercermin dalam konfigurasi aplikasi klien. Klien dapat memilih transportasi dan protokol dengan memilih endpointConfigurationName yang sesuai.

// Create a client using either wsat or oletx endpoint configurations
CalculatorClient client = new CalculatorClient("WSAtomicTransaction_endpoint");
// CalculatorClient client = new CalculatorClient("OleTransactions_endpoint");

Catatan

Perilaku yang diamati dari sampel ini adalah sama tidak peduli protokol atau transportasi mana yang dipilih.

Setelah memulai koneksi ke layanan, klien membuat TransactionScope baru di sekitar panggilan ke operasi layanan.

// Start a transaction scope
using (TransactionScope tx =
            new TransactionScope(TransactionScopeOption.RequiresNew))
{
    Console.WriteLine("Starting transaction");

    // Call the Add service operation
    //  - generatedClient will flow the required active transaction
    double value1 = 100.00D;
    double value2 = 15.99D;
    double result = client.Add(value1, value2);
    Console.WriteLine("  Add({0},{1}) = {2}", value1, value2, result);

    // Call the Subtract service operation
    //  - generatedClient will flow the allowed active transaction
    value1 = 145.00D;
    value2 = 76.54D;
    result = client.Subtract(value1, value2);
    Console.WriteLine("  Subtract({0},{1}) = {2}", value1, value2, result);

    // Start a transaction scope that suppresses the current transaction
    using (TransactionScope txSuppress =
                new TransactionScope(TransactionScopeOption.Suppress))
    {
        // Call the Subtract service operation
        //  - the active transaction is suppressed from the generatedClient
        //    and no transaction will flow
        value1 = 21.05D;
        value2 = 42.16D;
        result = client.Subtract(value1, value2);
        Console.WriteLine("  Subtract({0},{1}) = {2}", value1, value2, result);

        // Complete the suppressed scope
        txSuppress.Complete();
    }

    // Call the Multiply service operation
    // - generatedClient will not flow the active transaction
    value1 = 9.00D;
    value2 = 81.25D;
    result = client.Multiply(value1, value2);
    Console.WriteLine("  Multiply({0},{1}) = {2}", value1, value2, result);

    // Call the Divide service operation.
    // - generatedClient will not flow the active transaction
    value1 = 22.00D;
    value2 = 7.00D;
    result = client.Divide(value1, value2);
    Console.WriteLine("  Divide({0},{1}) = {2}", value1, value2, result);

    // Complete the transaction scope
    Console.WriteLine("  Completing transaction");
    tx.Complete();
}

Console.WriteLine("Transaction committed");

Panggilan ke operasi adalah sebagai berikut:

  • Permintaan Add mengalirkan transaksi yang diperlukan ke layanan dan tindakan layanan terjadi dalam cakupan transaksi klien.

  • Permintaan Subtract mengalirkan transaksi yang diizinkan ke layanan dan sekali lagi tindakan layanan terjadi dalam cakupan transaksi klien.

  • Permintaan Subtract kedua dilakukan dalam cakupan transaksi baru yang dinyatakan dengan opsi TransactionScopeOption.Suppress. Hal ini menekan transaksi luar awal klien dan permintaan tidak mengalirkan transaksi ke layanan. Pendekatan ini memungkinkan klien untuk secara eksplisit memilih keluar dari dan melindungi dari aliran transaksi ke layanan saat hal itu tidak diperlukan. Tindakan layanan terjadi dalam cakupan transaksi baru dan tidak tersambung.

  • Permintaan Multiply tidak mengalirkan transaksi ke layanan karena definisi antarmuka ICalculator yang dihasilkan klien mencakup TransactionFlowAttribute yang diatur ke TransactionFlowOptionNotAllowed.

  • Permintaan Divide tidak mengalirkan transaksi ke layanan karena definisi antarmuka ICalculator yang dihasilkan klien tidak mencakup TransactionFlowAttribute. Tindakan layanan kembali terjadi dalam cakupan transaksi baru dan tidak tersambung lainnya.

Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Tekan ENTER di jendela klien untuk mematikan komputer klien.

Starting transaction
  Add(100,15.99) = 115.99
  Subtract(145,76.54) = 68.46
  Subtract(21.05,42.16) = -21.11
  Multiply(9,81.25) = 731.25
  Divide(22,7) = 3.14285714285714
  Completing transaction
Transaction committed
Press <ENTER> to terminate client.

Pengelogan permintaan operasi layanan ditampilkan di jendela konsol layanan. Tekan ENTER di jendela klien untuk mematikan komputer klien.

Press <ENTER> to terminate the service.
  Writing row to database: Adding 100 to 15.99
  Writing row to database: Subtracting 76.54 from 145
  Writing row to database: Subtracting 42.16 from 21.05
  Writing row to database: Multiplying 9 by 81.25
  Writing row to database: Dividing 22 by 7

Setelah eksekusi berhasil, cakupan transaksi klien selesai dan semua tindakan yang diambil dalam cakupan tersebut diterapkan. Secara khusus, 5 rekaman yang tercatat disimpan dalam database layanan. Dua rekaman pertama telah muncul dalam cakupan transaksi klien.

Jika pengecualian terjadi di mana saja dalam TransactionScope komputer klien, transaksi tidak dapat diselesaikan. Hal ini menyebabkan rekaman yang dicatat dalam cakupan tersebut tidak diterapkan pada database. Efek ini dapat diamati dengan mengulangi eksekusi sampel setelah mengomentari panggilan untuk menyelesaikan TransactionScope luar. Pada eksekusi seperti itu, hanya 3 tindakan terakhir (dari permintaan Subtract, Multiply dan Divide yang kedua) yang dicatat karena transaksi klien tidak mengalir ke tindakan tersebut.

Untuk menyiapkan, membangun, dan menjalankan sampel

  1. Untuk membangun solusi versi C# atau Visual Basic .NET, ikuti instruksi dalam Membangun Sampel Windows Communication Foundation

  2. Pastikan Anda telah menginstal SQL Server Express Edition atau SQL Server, dan bahwa string koneksi telah diatur dengan benar dalam file konfigurasi aplikasi layanan. Untuk menjalankan sampel tanpa menggunakan database, atur nilai usingSql dalam file konfigurasi aplikasi layanan ke false

  3. Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi pada Menjalankan Sampel WCF.

    Catatan

    Untuk konfigurasi lintas komputer, aktifkan Koordinator Transaksi Terdistribusi menggunakan instruksi di bawah ini, dan gunakan alat WsatConfig.exe dari SDK Windows untuk mengaktifkan dukungan jaringan Transaksi WCF. Untuk informasi tentang menyiapkan WsatConfig.exe, lihat Mengonfigurasi Dukungan Transaksi WS-Atomic.

Entah Anda menjalankan sampel di komputer yang sama atau di komputer yang berbeda, Anda harus mengonfigurasi Koordinator Transaksi Terdistribusi Microsoft (MSDTC) untuk mengaktifkan aliran transaksi jaringan dan menggunakan alat WsatConfig.exe untuk mengaktifkan dukungan jaringan transaksi WCF.

Untuk mengonfigurasi Koordinator Transaksi Terdistribusi Microsoft (MSDTC) untuk mendukung eksekusi sampel

  1. Pada komputer layanan yang menjalankan Windows Server 2003 atau Windows XP, konfigurasikan MSDTC untuk memungkinkan transaksi jaringan masuk dengan mengikuti instruksi ini.

    1. Dari menu Start, buka Panel Kontrol, lalu Alat Administrasi, lalu Layanan Komponen.

    2. Luaskan Layanan Komponen. Buka folder Komputer.

    3. Klik kanan Komputer Saya dan pilih Properti.

    4. Pada tab MSDTC, klik Konfigurasi Keamanan.

    5. Periksa Akses DTC Jaringan dan Izinkan Masuk.

    6. Klik OK, lalu klik Ya untuk menghidupkan ulang layanan MSDTC.

    7. Klik OK untuk menutup kotak dialog.

  2. Pada komputer layanan yang menjalankan Windows Server 2008 atau Windows Vista, konfigurasikan MSDTC untuk mengizinkan transaksi jaringan masuk dengan mengikuti instruksi ini.

    1. Dari menu Start, buka Panel Kontrol, lalu Alat Administrasi, lalu Layanan Komponen.

    2. Luaskan Layanan Komponen. Buka folder Komputer. Pilih Koordinator Transaksi Terdistribusi.

    3. Klik kanan Koordinator DTC dan pilih Properti.

    4. Pada tab Keamanan, centang Akses DTC Jaringan dan Izinkan Masuk.

    5. Klik OK, lalu klik Ya untuk menghidupkan ulang layanan MSDTC.

    6. Klik OK untuk menutup kotak dialog.

  3. Pada mesin klien, konfigurasikan MSDTC untuk memungkinkan transaksi jaringan keluar:

    1. Dari menu Mulai, buka Control Panel, lalu Alat Administratif, lalu Layanan Komponen.

    2. Klik kanan Komputer Saya dan pilih Properti.

    3. Pada tab MSDTC, klik Konfigurasi Keamanan.

    4. Centang Akses DTC Jaringan dan Izinkan Keluar.

    5. Klik OK, lalu klik Ya untuk menghidupkan ulang layanan MSDTC.

    6. Klik OK untuk menutup kotak dialog.