Pesan transaksional adalah jenis pesan unggulan yang disediakan oleh ApsaraMQ for RocketMQ. Dokumen ini menjelaskan skenario, mekanisme kerja, batasan, metode penggunaan, serta catatan penting terkait pesan transaksional.
Skenario
Transaksi terdistribusi
Dalam sistem terdistribusi, logika bisnis inti sering kali memerlukan pemrosesan simultan oleh beberapa sistem hilir. Masalah utama dalam transaksi terdistribusi adalah memastikan konsistensi hasil antara sistem bisnis inti dan sistem hilir.

Sebagai contoh dalam skenario e-commerce, ketika pengguna melakukan pemesanan, perubahan juga dipicu di sistem hilir seperti logistik, poin kredit, dan keranjang belanja. Berikut adalah cabang-cabang transaksi yang terlibat:
Sistem pesanan: Status pesanan berubah dari belum dibayar menjadi telah dibayar.
Sistem logistik: Menambahkan catatan pengiriman dan membuat entri logistik.
Sistem poin: Memperbarui poin kredit pengguna.
Sistem keranjang belanja: Membersihkan item dan memperbarui catatan pengguna.
Solusi transaksi berbasis XA tradisional: performa buruk
Solusi umum untuk memastikan konsistensi hasil di antara cabang-cabang transaksi adalah menggunakan sistem transaksi terdistribusi berbasis protokol eXtended Architecture (XA). Solusi ini mengenkapsulasi perubahan ke dalam transaksi besar yang mencakup empat cabang transaksi independen. Meskipun solusi ini menjamin konsistensi hasil, sejumlah besar sumber daya harus dikunci selama pemrosesan, menyebabkan konkurensi rendah dan performa buruk. Jumlah sumber daya yang dikunci meningkat seiring dengan jumlah cabang transaksi.
Solusi berbasis pesan normal: konsistensi hasil buruk
Solusi alternatif yang lebih sederhana menganggap perubahan di sistem pesanan sebagai transaksi lokal dan perubahan di sistem hilir sebagai tugas hilir. Cabang-cabang transaksi dianggap sebagai transaksi pesan normal dan tabel pesanan. Solusi ini memproses pesan secara asinkron untuk mempersingkat waktu pemrosesan dan meningkatkan konkurensi sistem.

Namun, solusi ini dapat menghasilkan ketidaksesuaian antara transaksi inti dan cabang-cabang transaksi. Contohnya:
Pesan dikirim, tetapi pesanan belum selesai. Dalam hal ini, seluruh transaksi harus dibatalkan.
Pesanan selesai, tetapi pesan tidak dikirim. Dalam hal ini, pesan harus dikirim ulang untuk dikonsumsi.
Kesalahan timeout tidak dapat dideteksi secara andal, sehingga sulit untuk menentukan apakah pesanan perlu dibatalkan atau perubahan pesanan perlu dikomit.
Solusi pesan transaksional ApsaraMQ for RocketMQ: konsistensi hasil
Solusi pesan normal tidak dapat menjamin konsistensi hasil karena kurangnya kemampuan commit, rollback, dan koordinasi terpadu seperti pada transaksi database standalone.
Solusi pesan transaksional yang disediakan oleh ApsaraMQ for RocketMQ mendukung commit dua fase. Solusi ini menggabungkan commit dua fase dengan transaksi lokal untuk memastikan konsistensi global hasil commit.

Solusi pesan transaksional ApsaraMQ for RocketMQ menawarkan performa tinggi, skalabilitas tinggi, dan kemudahan pengembangan bisnis. Untuk informasi lebih lanjut tentang mekanisme kerja dan alur pemrosesan pesan transaksional, lihat Mekanisme Kerja.
Mekanisme kerja
Apa itu pesan transaksional?
Pesan transaksional adalah jenis pesan unggulan yang disediakan oleh ApsaraMQ for RocketMQ untuk memastikan konsistensi akhir antara produksi pesan dan transaksi lokal.
Alur pemrosesan
Gambar berikut mengilustrasikan proses penggunaan pesan transaksional.
Produsen mengirim pesan ke broker ApsaraMQ for RocketMQ.
Broker ApsaraMQ for RocketMQ menyimpan pesan secara persisten dan mengembalikan acknowledgment (ACK) kepada produsen. Pada tahap ini, pesan ditandai sebagai "tidak siap untuk dikirim". Pesan dalam status ini disebut pesan setengah.
Produsen mengeksekusi transaksi lokal.
Produsen mengirimkan hasil eksekusi transaksi lokal ke broker. Hasil eksekusi dapat berupa Commit atau Rollback. Berikut adalah logika pemrosesan setelah broker menerima hasil eksekusi:
Jika hasil eksekusi adalah Commit, broker menandai pesan setengah sebagai "siap untuk dikirim" dan mengirimkan pesan ke konsumen.
Jika hasil eksekusi adalah Rollback, broker membatalkan transaksi dan tidak mengirimkan pesan setengah ke konsumen.
Jika broker tidak menerima hasil eksekusi atau status pesan setengah tidak diketahui karena pemutusan jaringan atau restart produsen, broker menunggu periode waktu tertentu dan mengirim permintaan ke produsen di kluster produsen untuk memeriksa status pesan setengah.
CatatanUntuk informasi tentang interval antara dua permintaan status dan jumlah maksimum permintaan, lihat Batasan Parameter.
Setelah produsen menerima permintaan untuk memeriksa status pesan setengah, produsen memeriksa hasil eksekusi transaksi lokal yang sesuai dengan pesan setengah.
Produsen mengirimkan hasil eksekusi ke broker berdasarkan status transaksi lokal yang diperiksa. Kemudian, broker melakukan operasi di Langkah 4 untuk memproses pesan setengah.
Siklus hidup pesan transaksional

Inisialisasi
Pesan setengah diproduksi dan diinisialisasi oleh produsen dan siap untuk dikirim ke broker.
Transaksi yang akan dikomit
Pesan setengah dikirim ke broker. Tidak seperti pesan normal, pesan setengah tidak disimpan secara persisten oleh broker. Sebaliknya, pesan setengah disimpan di sistem penyimpanan transaksi dan tidak dikomit sampai hasil eksekusi transaksi lokal dikembalikan. Pada fase ini, pesan tidak terlihat bagi konsumen hilir.
Pembatalan Pesan
Jika hasil eksekusi transaksi lokal adalah Rollback, broker membatalkan pesan setengah dan mengakhiri alur kerja.
Dikomit untuk Dikonsumsi
Jika hasil eksekusi transaksi lokal adalah Commit, broker menyimpan pesan setengah di sistem penyimpanan. Pesan menjadi terlihat dan siap untuk dikonsumsi oleh konsumen hilir.
Sedang Dikonsumsi
Pesan diperoleh oleh konsumen dan diproses berdasarkan logika konsumsi lokal yang ditentukan oleh konsumen.
Selama proses ini, broker menunggu konsumen mengembalikan hasil konsumsi. Jika tidak ada respons yang diterima dari konsumen dalam periode waktu tertentu, ApsaraMQ for RocketMQ melakukan upaya ulang pada pesan. Untuk informasi lebih lanjut, lihat Percobaan Konsumsi Ulang.
Komit Hasil Konsumsi
Konsumen menyelesaikan konsumsi dan mengirimkan hasil konsumsi ke broker. Broker menandai apakah pesan telah dikonsumsi.
Secara default, ApsaraMQ for RocketMQ menyimpan semua pesan. Ketika hasil konsumsi dikomit, pesan ditandai sebagai telah dikonsumsi alih-alih langsung dihapus. Pesan hanya dihapus jika masa retensi habis atau sistem kehabisan ruang penyimpanan. Sebelum pesan dihapus, konsumen dapat mengonsumsi ulang pesan tersebut.
Penghapusan Pesan
Jika masa retensi pesan habis atau ruang penyimpanan tidak mencukupi, ApsaraMQ for RocketMQ menghapus pesan yang tersimpan paling awal dari file fisik secara bergulir. Untuk informasi lebih lanjut, lihat Penyimpanan dan Pembersihan Pesan.
Batasan
Konsistensi jenis pesan
Pesan transaksional hanya dapat digunakan di topik yang MessageType-nya diatur ke Transaction.
Konsumsi berpusat pada transaksi
Pesan transaksional yang disediakan oleh ApsaraMQ for RocketMQ hanya memastikan konsistensi hasil antara transaksi inti lokal dan cabang-cabang transaksi hilir. Sistem bisnis hilir harus memastikan bahwa pesan diproses dengan benar. Kami merekomendasikan agar konsumen melakukan percobaan konsumsi ulang dengan tepat untuk memastikan pemrosesan pesan yang berhasil. Untuk informasi lebih lanjut, lihat Percobaan Konsumsi Ulang.
Visibilitas status perantara
Pesan transaksional yang disediakan oleh ApsaraMQ for RocketMQ hanya memastikan konsistensi hasil. Ketidaksesuaian status antara cabang-cabang transaksi hilir dan transaksi hulu ada sebelum pesan dikirim ke konsumen. Oleh karena itu, pesan transaksional cocok hanya untuk skenario transaksi di mana eksekusi asinkron dapat digunakan.
Mekanisme timeout transaksi
Mekanisme timeout digunakan dalam siklus hidup pesan transaksional yang disediakan oleh ApsaraMQ for RocketMQ. Setelah broker menerima pesan setengah, pesan tersebut secara default dibatalkan jika broker tidak dapat menentukan hasil eksekusi pesan transaksi. Untuk informasi lebih lanjut, lihat Batasan Parameter.
Multiple SendReceipts tidak didukung
Hanya satu SendReceipt yang diizinkan untuk pesan transaksional dalam satu transaksi.
Contoh kode
Pengiriman pesan transaksional berbeda dari pengiriman pesan normal dalam aspek-aspek berikut:
Sebelum mengirim pesan transaksional, Anda harus mengaktifkan pemeriksa transaksi dan mengaitkannya dengan eksekusi transaksi lokal.
Untuk memastikan konsistensi transaksi, Anda harus mengonfigurasi pemeriksa transaksi dan mengikat topik tempat Anda ingin mengirim pesan saat membangun produsen. Jika pengecualian terjadi pada topik yang terikat, pemeriksa transaksi bawaan dapat digunakan untuk memulihkan status.
Contoh kode berikut memberikan ilustrasi cara menggunakan pesan transaksional dalam Java.
Untuk informasi tentang kode contoh lengkap untuk perpesanan, lihat Apache RocketMQ 5.x SDKs (Direkomendasikan).
Contoh kode
Catatan penggunaan
Cegah timeout yang disebabkan oleh transaksi dengan hasil tidak diketahui
ApsaraMQ for RocketMQ memungkinkan Anda memulai permintaan untuk memeriksa status transaksi lokal jika pengecualian terjadi dalam fase commit transaksi untuk memastikan konsistensi transaksional. Namun, produsen harus mencegah transaksi lokal mengembalikan hasil yang tidak diketahui. Sejumlah besar pemeriksaan transaksi dapat memburuknya performa sistem dan menyebabkan penundaan dalam pemrosesan transaksi.
Tangani transaksi yang sedang berlangsung dengan benar
Selama pemeriksaan status transaksi lokal, jangan kembalikan Rollback atau Commit untuk transaksi yang sedang berlangsung. Sebagai gantinya, pertahankan status Tidak Diketahui untuk transaksi.
Dalam kebanyakan kasus, transaksi sedang berlangsung karena eksekusi transaksi lambat dan pemeriksaan status transaksi lokal terlalu cepat. Solusi berikut disediakan:
Tentukan nilai yang lebih besar untuk waktu melakukan pemeriksaan pertama status transaksi lokal. Ini dapat menyebabkan penundaan besar untuk transaksi yang bergantung pada hasil query.
Buat program dengan benar mengidentifikasi transaksi yang sedang berlangsung.