Bagikan melalui


Perilaku Transaksi Layanan

Sampel Transaksi menunjukkan penggunaan transaksi yang dikoordinasikan klien dan pengaturan ServiceBehaviorAttribute dan OperationBehaviorAttribute untuk mengontrol perilaku transaksi layanan. Sampel ini didasarkan pada sampel Memulai yang mengimplementasikan layanan kalkulator, tetapi diperluas untuk mempertahankan log server dari operasi yang dilakukan dalam tabel database dan total yang berjalan secara stateful untuk operasi kalkulator. Penulisan terus-menerus ke tabel log server bergantung pada hasil transaksi terkoordinasi klien - jika transaksi klien tidak selesai, transaksi layanan Web memastikan bahwa pembaruan ke database tidak dilakukan.

Catatan

Prosedur penyiapan dan instruksi pembuatan untuk sampel ini ada di akhir artikel ini.

Kontrak untuk layanan mendefinisikan bahwa semua operasi memerlukan transaksi yang akan dialirkan dengan permintaan:

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

Untuk mengaktifkan alur transaksi masuk, layanan dikonfigurasi dengan wsHttpBinding yang disediakan sistem dengan atribut transactionFlow yang diatur ke true. Pengikatan ini menggunakan protokol WSATomicTransactionOctober2004 yang memiliki interoperabilitas:

<bindings>
  <wsHttpBinding>
    <binding name="transactionalBinding" transactionFlow="true" />
  </wsHttpBinding>
</bindings>

Setelah memulai koneksi ke layanan dan transaksi, klien mengakses beberapa operasi layanan dalam lingkup transaksi itu dan kemudian menyelesaikan transaksi dan menutup koneksi:

// Create a client
CalculatorClient client = new CalculatorClient();

// Create a transaction scope with the default isolation level of Serializable
using (TransactionScope tx = new TransactionScope())
{
    Console.WriteLine("Starting transaction");

    // Call the Add service operation.
    double value = 100.00D;
    Console.WriteLine("  Adding {0}, running total={1}",
                                        value, client.Add(value));

    // Call the Subtract service operation.
    value = 45.00D;
    Console.WriteLine("  Subtracting {0}, running total={1}",
                                        value, client.Subtract(value));

    // Call the Multiply service operation.
    value = 9.00D;
    Console.WriteLine("  Multiplying by {0}, running total={1}",
                                        value, client.Multiply(value));

    // Call the Divide service operation.
    value = 15.00D;
    Console.WriteLine("  Dividing by {0}, running total={1}",
                                        value, client.Divide(value));

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

Console.WriteLine("Transaction committed");

// Closing the client gracefully closes the connection and cleans up resources
client.Close();

Pada layanan, ada tiga atribut yang mempengaruhi perilaku transaksi layanan, dan mereka melakukannya dengan cara berikut:

  • Di ServiceBehaviorAttribute:

    • Properti TransactionTimeout menentukan periode waktu di mana transaksi harus diselesaikan. Dalam sampel ini diatur ke 30 detik.

    • Properti TransactionIsolationLevel menentukan tingkat isolasi yang didukung layanan. Ini diperlukan agar sesuai dengan tingkat isolasi klien.

    • Properti ReleaseServiceInstanceOnTransactionComplete menentukan apakah instans layanan didaur ulang saat transaksi selesai. Dengan mengaturnya ke false, layanan mempertahankan instans layanan yang sama di seluruh permintaan operasi. Ini diperlukan untuk mempertahankan total berjalan. Jika diatur ke true, instans baru dihasilkan setelah setiap tindakan selesai.

    • Properti TransactionAutoCompleteOnSessionClose menentukan apakah transaksi yang belum selesai diselesaikan saat sesi ditutup. Dengan mengaturnya ke false, operasi individual diharuskan untuk mengatur properti OperationBehaviorAttribute.TransactionAutoComplete ke true atau secara eksplisit meminta panggilan ke metode OperationContext.SetTransactionComplete() untuk menyelesaikan transaksi. Sampel ini menunjukkan kedua pendekatan tersebut.

  • Di ServiceContractAttribute:

    • Properti SessionMode menentukan apakah layanan menghubungkan permintaan yang sesuai ke dalam sesi logis. Karena layanan ini mencakup operasi di mana properti OperationBehaviorAttribute TransactionAutoComplete diatur ke false (Perkalian dan Pembagian), SessionMode.Required harus ditentukan. Misalnya, operasi Perkalian tidak menyelesaikan transaksinya dan sebaliknya bergantung pada panggilan selanjutnya ke Pembagian untuk diselesaikan menggunakan metode SetTransactionComplete; layanan harus dapat menentukan bahwa operasi ini terjadi dalam sesi yang sama.
  • Di OperationBehaviorAttribute:

    • Properti TransactionScopeRequired menentukan apakah tindakan operasi harus dijalankan dalam cakupan transaksi. Ini diatur ke true untuk semua operasi dalam sampel ini dan, karena klien mengalirkan transaksinya ke semua operasi, tindakan terjadi dalam cakupan transaksi klien tersebut.

    • Properti TransactionAutoComplete menentukan apakah transaksi di mana metode dijalankan akan diselesaikan secara otomatis jika tidak ada pengecualian yang tidak ditangani. Seperti yang dijelaskan sebelumnya, ini diatur ke true untuk operasi Tambah dan Kurangi tetapi false untuk operasi Perkalian dan Pembagian. Operasi Tambah dan Kurangi menyelesaikan tindakannya secara otomatis, Pembagian menyelesaikan tindakannya melalui panggilan eksplisit ke metode SetTransactionComplete, dan Perkalian tidak menyelesaikan tindakannya melainkan bergantung pada dan membutuhkan panggilan berikutnya, seperti Pembagian, untuk menyelesaikan tindakan.

Implementasi layanan yang dikaitkan adalah sebagai berikut:

[ServiceBehavior(
    TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable,
    TransactionTimeout = "00:00:30",
    ReleaseServiceInstanceOnTransactionComplete = false,
    TransactionAutoCompleteOnSessionClose = false)]
public class CalculatorService : ICalculator
{
    double runningTotal;

    public CalculatorService()
    {
        Console.WriteLine("Creating new service instance...");
    }

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public double Add(double n)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Adding {0} to {1}", n, runningTotal));
        runningTotal = runningTotal + n;
        return runningTotal;
    }

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

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

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = false)]
    public double Divide(double n)
    {
        RecordToLog(String.Format(CultureInfo.CurrentCulture, "Dividing {0} by {1}", runningTotal, n));
        runningTotal = runningTotal / n;
        OperationContext.Current.SetTransactionComplete();
        return runningTotal;
    }

    // Logging method omitted for brevity
}

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

Starting transaction
Performing calculations...
  Adding 100, running total=100
  Subtracting 45, running total=55
  Multiplying by 9, running total=495
  Dividing by 15, running total=33
  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 service.
Creating new service instance...
  Writing row 1 to database: Adding 100 to 0
  Writing row 2 to database: Subtracting 45 from 100
  Writing row 3 to database: Multiplying 55 by 9
  Writing row 4 to database: Dividing 495 by 15

Perhatikan bahwa selain menjaga total perhitungan tetap berjalan, layanan melaporkan pembuatan instans (satu instans untuk sampel ini) dan mencatat permintaan operasi ke database. Karena semua permintaan mengalir transaksi klien, setiap kegagalan untuk menyelesaikan transaksi yang mengakibatkan semua operasi database yang digulirkan kembali. Hal ini dapat ditunjukkan dalam beberapa cara:

  • Komentari panggilan klien ke tx.Complete() dan jalankan kembali - ini mengakibatkan klien keluar dari cakupan transaksi tanpa menyelesaikan transaksinya.

  • Mengomentari panggilan ke operasi layanan Pembagian - hasil ini mencegah penyelesaian tindakan yang dimulai oleh operasi Perkalian dan dengan demikian transaksi klien pada akhirnya juga gagal diselesaikan.

  • Lempar pengecualian yang tidak tertangani di mana pun dalam lingkup transaksi klien - ini juga mencegah klien menyelesaikan transaksinya.

Hasil dari semua ini adalah bahwa tidak ada operasi yang dilakukan dalam lingkup itu yang dilakukan dan jumlah baris yang dipertahankan ke database tidak bertambah.

Catatan

Sebagai bagian dari proses pembuatan, file database disalin ke folder bin. Anda harus melihat salinan file database tersebut untuk mengamati baris yang disimpan ke log daripada file yang disertakan dalam proyek Visual Studio.

Untuk menyiapkan, membangun, dan menjalankan sampel

  1. Pastikan Anda telah menginstal SQL Server 2005 Express Edition atau SQL Server 2005. Dalam file App.config layanan, basis data connectionString dapat diatur atau interaksi database dapat dinonaktifkan dengan mengatur nilai usingSql appSettings ke false.

  2. Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti petunjuknya di Membangun Sampel WCF.

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

Jika Anda menjalankan sampel di seluruh mesin, Anda harus mengonfigurasi Koordinator Transaksi Terdistribusi Microsoft (MSDTC) untuk mengaktifkan aliran transaksi jaringan dan menggunakan alat WsatConfig.exe untuk mengaktifkan dukungan jaringan transaksi Windows Communication Foundation (WCF).

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

  1. Pada mesin layanan, konfigurasikan MSDTC untuk mengizinkan transaksi jaringan masuk.

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

    2. Klik kanan Komputer Saya dan pilih Properti.

    3. Pada tab MSDTC, klik Konfigurasi Keamanan.

    4. Periksa Akses DTC Jaringan dan Izinkan Masuk.

    5. Klik Ya untuk memulai ulang layanan MS DTC lalu klik OK.

    6. Klik OK untuk menutup kotak dialog.

  2. Pada mesin layanan dan mesin klien, konfigurasikan Windows Firewall untuk menyertakan Koordinator Transaksi Terdistribusi Microsoft (MSDTC) ke daftar aplikasi yang dikecualikan:

    1. Jalankan aplikasi Windows Firewall dari Panel Kontrol.

    2. Dari tab Pengecualian, klik Tambahkan Program.

    3. Telusuri ke folder C:\WINDOWS\System32.

    4. Pilih Msdtc.exe dan klik Buka.

    5. Klik OK untuk menutup kotak dialog Tambahkan Program, dan klik OK lagi untuk menutup applet Windows Firewall.

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

    1. Dari menu Start, buka Panel Kontrol, lalu Alat Administrasi, 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 Ya untuk memulai ulang layanan MS DTC lalu klik OK.

    6. Klik OK untuk menutup kotak dialog.