Alur Transaksi Layanan Web

Sampel TransactionFlow menunjukkan penggunaan transaksi yang dikoordinasikan klien dan opsi klien dan server untuk alur transaksi menggunakan protokol Transaksi WS-Atomic atau OleTransactions. Sampel ini didasarkan pada Memulai yang mengimplementasikan layanan kalkulator, namun operasi-operasi ini diatributkan untuk mendemonstrasikan penggunaan TransactionFlowAttribute dengan enumerasi TransactionFlowOption untuk menentukan sejauh mana aliran transaksi diaktifkan. Dalam cakupan transaksi yang mengalir, log operasi yang diminta ditulis ke database dan bertahan hingga transaksi terkoordinasi klien selesai - jika transaksi klien tidak selesai, transaksi layanan Web memastikan bahwa pembaruan database yang sesuai tidak dilakukan.

Nota

Prosedur penyiapan dan instruksi build untuk sampel ini terletak di akhir topik ini.

Setelah memulai koneksi ke layanan dan transaksi, klien mengakses beberapa operasi layanan. Kontrak untuk layanan dijelaskan sebagai berikut, dengan setiap operasi menunjukkan pengaturan 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);
}

Ini mendefinisikan operasi dalam urutan yang akan diproses:

  • Permintaan operasi Add harus menyertakan transaksi yang terproses.

  • Permintaan operasi Subtract dapat mencakup transaksi yang mengalir.

  • Permintaan operasi Multiply tidak boleh menyertakan transaksi yang sedang diproses melalui pengaturan "NotAllowed" yang eksplisit.

  • Permintaan operasi Divide tidak boleh menyertakan transaksi yang diproses akibat tidak adanya atribut TransactionFlow.

Untuk mengaktifkan alur transaksi, selain atribut operasi yang sesuai, harus digunakan pengikatan dengan properti <transactionFlow> yang diaktifkan. 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>

Nota

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 diberi atribut 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 perekaman ke database log. Jika permintaan operasi menyertakan transaksi yang mengalir, maka tindakan terjadi dalam cakupan transaksi masuk atau cakupan transaksi baru dibuat secara otomatis.

Nota

Properti TransactionScopeRequired mendefinisikan perilaku lokal ke 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 endpointConfigurationNameyang sesuai.

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

Nota

Perilaku yang diamati dari sampel ini sama, terlepas dari protokol atau transportasi mana yang dipilih.

Setelah memulai koneksi ke layanan, klien membuat TransactionScope baru untuk mengelola 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 pertama juga 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 dideklarasikan dengan opsi TransactionScopeOption.Suppress. Ini menekan transaksi luar awal klien dan permintaan tidak mengalirkan transaksi ke layanan. Pendekatan ini memungkinkan klien untuk secara eksplisit menolak dan melindungi dari mengalirkan transaksi ke layanan ketika itu tidak diperlukan. Tindakan layanan terjadi dalam cakupan transaksi baru tanpa keterhubungan.

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

  • Permintaan Divide tidak mengalirkan transaksi ke layanan karena sekali lagi definisi klien yang dihasilkan dari antarmuka ICalculator tidak menyertakan TransactionFlowAttribute. Aksi layanan kembali terjadi dalam lingkup transaksi baru yang lain dan tidak terkait.

Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Tekan ENTER di jendela klien untuk mematikan 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 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 dilakukan. Secara khusus, 5 catatan yang tercatat disimpan dalam database layanan. Dua yang pertama dari ini telah terjadi dalam lingkup transaksi klien.

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

Untuk menyiapkan, mengompilasi, dan menjalankan sampel

  1. Untuk membangun versi C# atau Visual Basic .NET solusi, ikuti instruksi di 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 di Menjalankan Sampel Windows Communication Foundation.

    Nota

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

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

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

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

    1. Dari menu Mulai, navigasikan ke Panel Kontrol, lalu Alat Administratif, lalu Layanan Komponen.

    2. Perluas 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 IzinkanMasuk .

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

    7. Klik OK untuk menutup kotak dialog.

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

    1. Dari menu Mulai, navigasikan ke Panel Kontrol, lalu Alat Administratif, lalu Layanan Komponen.

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

    3. Klik kanan Koordinator DTC dan pilih properti .

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

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

    6. Klik OK untuk menutup kotak dialog.

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

    1. Dari menu Mulai, navigasikan ke Control Panel, lalu ke Alat Administratif, dan kemudian ke Layanan Komponen.

    2. Klik kanan Komputer Saya dan pilih Properti .

    3. Pada tab MSDTC, klik Konfigurasi Keamanan.

    4. Periksa Akses DTC Jaringan dan serta Izinkan Keluar.

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

    6. Klik OK untuk menutup kotak dialog.