Menangani Transaksi
Penerima yang Ditransaksikan
Perbedaan utama antara penerima yang ditransaksikan dan penerima yang tidak ditransaksikan adalah penerima yang ditransaksikan membuat dan menggunakan transaksi MSDTC eksplisit untuk memastikan atomitas antara sumber data mereka dan database BizTalk Server MessageBox. Secara umum setiap aspek lain dari adaptor adalah sama.
Perlu dicatat bahwa adaptor penerima permintaan-respons hanya menggunakan transaksi untuk mengirimkan pesan permintaan asli ke Mesin Olahpesan. Transaksi yang berbeda diperlukan untuk transmisi respons yang dikirim dari Mesin Olahpesan ke adaptor. Ini karena cakupan transaksi pertama adalah antara adaptor dan database MessageBox. Pesan permintaan berikutnya tidak dikirim ke adaptor dari Mesin Olahpesan hingga transaksi untuk pesan permintaan asli diterapkan.
Diagram interaksi objek berikut mengilustrasikan interaksi antara adaptor dan Mesin Olahpesan selama pengiriman transaksional pesan masuk. Dalam contoh ini, urutan interaksi berikut terjadi:
Adaptor mendapatkan batch baru dari mesin.
Adaptor membuat transaksi MSDTC baru.
Adaptor melakukan pembacaan merusak dari sumber datanya yang telah terdaftar dalam transaksi.
Adaptor mengirimkan pesan.
Adaptor memanggil Selesai pada batch, meneruskan transaksi MSDTC dan penunjuk panggilan balik BatchComplete-nya . Mesin mengembalikan antarmuka IBTDTCCommitConfirm .
Mesin memproses batch, memanggil adaptor kembali pada implementasi BatchComplete-nya , dan menyampaikan status pemrosesan pesannya ke adaptor.
Jika batch berhasil, adaptor melakukan transaksi dan memanggil IBTDTCCommitConfirm.DTCCommitConfirm API dengan
true
nilai yang menandakan penerapan.
Pemancar yang Ditransaksikan
Adaptor yang ditransaksikan adalah untuk sebagian besar sangat mirip dengan adaptor yang tidak ditransaksikan. Perbedaan utamanya adalah adaptor yang ditransaksikan mengirim data dalam pesan ke sumber daya yang telah terdaftar dalam transaksi MSDTC.
Tip Implementasi: Untuk pengiriman yang ditransaksikan, adaptor harus menggunakan transaksi MSDTC yang sama untuk menulis data ke tujuan dan untuk menghapusnya melalui panggilan metode IBTTransportBatch.DeleteMessage . Hanya kedua operasi ini yang perlu ditransaksikan. Setiap operasi lain, seperti IBTTransportBatch.Resubmit, IBTTransportBatch.MoveToNextTransport, dan IBTTransportBatch.MoveToSuspendQ tidak perlu ditransaksikan. Ini karena mesin secara implisit menggunakan transaksi dan jenis operasi ini tidak perlu atomik sehubungan dengan tujuan.
Diagram interaksi objek berikut mengilustrasikan interaksi antara adaptor dan mesin. Urutan peristiwanya adalah sebagai berikut:
Mesin mendapatkan batch baru dari adaptor.
Mesin menambahkan dua pesan ke batch baru.
Mesin memanggil Selesai pada batch, menyebabkan adaptor memposting batch ke antrean transmisi internalnya yang dilayankan oleh kumpulan utasnya.
Adaptor membuat transaksi MSDTC baru.
Adaptor mengirimkan pesan yang mendaftarkan tujuan dalam transaksi MSDTC. Misalnya, ini bisa menulis ke database SQL Server.
Setelah transmisi, adaptor mendapatkan batch baru dari mesin.
Adaptor memanggil DeleteMessage untuk pesan yang berhasil dikirimkan.
Adaptor memanggil Selesai pada batch yang melewati transaksi DTC-nya. Mesin mengembalikan antarmuka IBTDTCCommitConfirm .
Mesin memproses batch, menghapus pesan dari antrean aplikasi.
Mesin memanggil kembali antarmuka IBTBatchCallback adaptor dengan informasi tentang keberhasilan operasi penghapusannya.
Jika batch berhasil, adaptor melakukan transaksi.
Adaptor memanggil IBTDTCCommitConfirm.DTCCommitConfirm untuk memberi tahu mesin bahwa transaksi berhasil dilakukan.
Adaptor Solicit-Response yang ditransaksikan
Tidak seperti penerimaan dua arah, pengiriman dua arah dapat dilakukan dengan menggunakan transaksi DTC yang sama. Adaptor respons solitik yang ditransaksikan harus menggunakan IBTTransportBatch yang sama untuk operasi SubmitResponseMessage dan DeleteMessage . Batch ini harus menggunakan transaksi MSDTC yang sama yang digunakan untuk mengirim dan menerima pasangan pesan solicit-response. Ini memastikan atomitas untuk pertukaran pesan solicit-response.
Komponen Layanan dan BYOT
API Mesin Olahpesan memerlukan transaksi MSDTC untuk disediakan. Namun beberapa komponen .NET dirancang untuk digunakan sebagai komponen berlayanan dan tidak memungkinkan transaksi diterapkan atau dibatalkan secara terprogram. Sebaliknya, transaksi secara otomatis dilakukan oleh runtime COM+ pada platform tersebut.
Untuk skenario ini, adaptor harus menggunakan Bring Your Own Transaction (BYOT). Ini memungkinkan adaptor untuk membuat transaksi MSDTC, membuat instans komponen .NET yang menggunakan transaksi, dan memungkinkan komponen tersebut untuk mewarisi transaksi yang dibuat daripada membuat transaksinya sendiri. .NET Framework menyediakan System.EnterpriseServices.BYOT untuk tujuan ini. BaseAdapter SDK menyediakan kelas pembantu, BYOTTransaction, untuk tujuan ini.
Menghindari Kondisi Balapan
Saat Anda menulis adaptor yang membuat objek transaksi dan menyerahkannya ke BizTalk Server, Anda menerima tanggung jawab untuk menulis kode yang melakukan hal berikut:
Mengatasi kesalahan dalam pesan yang terkait dengan batch.
Memutuskan hasil akhir dari transaksi yang terkait dengan operasi batch.
Adaptor harus memberi tahu BizTalk Server tentang hasil akhir transaksi untuk mempertahankan data pelacakan internalnya. Adaptor menginformasikan BizTalk Server tentang hasil dengan memanggil DTCConfirmCommit. Jika adaptor tidak melakukan ini, kebocoran memori yang signifikan terjadi.
Dua tugas yang tercantum di atas (mengatasi kesalahan dan memutuskan hasil akhir) tampak cukup sederhana, tetapi sebenarnya mereka mengandalkan informasi dari utas yang berbeda:
Adaptor memproses kesalahan berdasarkan informasi yang diteruskan oleh BizTalk Server ke panggilan balik BatchComplete di adaptor. Panggilan balik ini ada di utas adaptor.
DTCConfirmCommit adalah metode pada objek IBTDTCCommitConfirm . Instans objek IBTDTCCommitConfirm dikembalikan oleh panggilan batch IBTTransportBatch::D one . Instans ini berada pada utas yang sama dengan panggilan IBTTransportBatch::D one , yang berbeda dari utas adaptor.
Untuk setiap panggilan yang dilakukan adaptor ke IBTTransportBatch::D ada panggilan balik yang sesuai, BatchComplete, yang dipanggil oleh Mesin Olahpesan dalam utas terpisah untuk melaporkan hasil pengiriman batch. Di BatchComplete , adaptor perlu menerapkan atau mengembalikan transaksi berdasarkan apakah batch lulus atau gagal. Dalam kedua kasus, adaptor kemudian harus memanggil DTCConfirmCommit untuk melaporkan status transaksi ke Mesin Olahpesan.
Kemungkinan kondisi balapan ada karena implementasi adaptor BatchComplete dapat mengasumsikan bahwa objek IBTDTCCommitConfirm yang dikembalikan oleh IBTTransportBatch::D one selalu tersedia ketika BatchComplete dijalankan. Namun, BatchComplete dapat dipanggil dalam utas Mesin Olahpesan terpisah, bahkan sebelum IBTTransportBatch::D one kembali. Ada kemungkinan bahwa ketika adaptor mencoba mengakses objek IBTDTCCommitConfirm sebagai bagian dari implementasi BatchComplete , ada pelanggaran akses.
Masalah diselesaikan dengan peristiwa dalam contoh berikut. Di sini penunjuk antarmuka diakses melalui properti yang menggunakan peristiwa. Get selalu menunggu set.
protected IBTDTCCommitConfirm CommitConfirm
{
set
{
this.commitConfirm = value;
this.commitConfirmEvent.Set();
}
get
{
this.commitConfirmEvent.WaitOne();
return this.commitConfirm;
}
}
protected IBTDTCCommitConfirm commitConfirm = null;
private ManualResetEvent commitConfirmEvent = new ManualResetEvent(false);
Sekarang tetapkan nilai pengembalian dari IBTTransportBatch::D satu ke properti ini dan gunakan dalam panggilan BatchComplete .