Mengapa ACID tidak bisa dilakukan pada arsitektur Microservices?
Pada monolith transaksi mengikuti ACID yang artinya semua transaksi sukses atau semuanya gagal (scope transaction), data selalu valid, eksekusi saling terisolasi, dan perubahan yang sudah commit akan dipertahankan. Pada arsitektur monolith single service + single database, hal ini sangat masuk akal dan relatif mudah diimplementasikan. Namun pada arsitektur microservices hal ini tidak dapat dilakukan. Lalu kenapa pada microservices tidak menggunakan two-phase commit (2PC)? Secara konseptual, 2PC memang dapat membuat semua pihak commit atau rollback bersama. Tetapi pada sistem cloud-native modern, pendekatan ini tidak disarankan karena akan menambah coupling, latensi, dan kompleksitas koordinasi, serta tidak selalu cocok dengan teknologi messaging dan microservices modern. Dalam microservices, kita tidak hanya mengelola data, tetapi juga komunikasi antar-service melalui event atau command. Itu berarti problemnya bukan sekadar commit database, tetapi juga bagaimana memastikan bahwa perubahan state di satu service sinkron dengan message yang memicu langkah berikutnya.
Dalam arsitektur microservices, Saga pattern digunakan untuk memecah transaksi bisnis antar microservice menjadi serangkaian transaksi lokal. setiap service menyelesaikan transaksinya sendiri, lalu memicu langkah berikutnya lewat event atau message. Jika salah satu langkah gagal, sistem menjalankan compensating transaction (mirip rollback pada monolith) untuk membatalkan transaksi/langkahyang sudah terlanjur dijalankan, sehingga konsistensi dapat dicapai secara eventual consistency alih-alih menggunakan ACID lintas database.
Mengapa penerapan Distributed Transaction paSulit?
Bayangkan sebuah platform e-commerce modern dibangun dengan beberapa microservice: Order Service, Payment Service, Inventory Service, dan Shipping Service. Ketika pelanggan membuat order, sistem harus menyimpan order, memproses pembayaran, mengurangi stok, lalu menjadwalkan pengiriman. Di monolith, semua langkah itu bisa dibungkus dalam satu transaksi database. Namun di microservices, setiap service biasanya memiliki database sendiri, sehingga ketika salah satu langkah gagal, dan misalnya stok habis setelah pembayaran berhasil maka akan muncul pertanyaan bagaimana menjaga agar sistem tidak berakhir dalam state yang inkonsisten? Problem seperti inilah yang mendorong penggunaan Saga Pattern pada arsitektur microservices.
Contoh skenario sederhana pada sistem checkout e-commerce:
- Order Service untuk membuat dan menyimpan order.
- Payment Service untuk mengotorisasi atau menerima pembayaran.
- Inventory Service untuk reservasi stok.
- Shipping Service untuk menjadwalkan pengiriman.
Dengan arsitektur monolith, kita mungkin menulis logika seperti berikut: buat order → proses pembayaran → reserve stok → schedule shipping → commit. Jika stok gagal di langkah ketiga, seluruh transaksi cukup di-rollback. Namun pada microservices, Order Service, Payment Service, Inventory Service, dan Shipping Service punya database sendiri (isolated database per services). Ketika Payment Service sudah sukses commit pembayaran, lalu Inventory Service gagal karena stok habis, kita tidak bisa lagi sekadar mengandalkan ROLLBACK tunggal. Kita butuh langkah bisnis baru seperti refund payment dan cancel order. Itulah mengapa kita butuh Saga Pattern.
Apa sebenarnya Saga Pattern?
Secara sederhana, Saga adalah urutan local transactions. Setiap service menyelesaikan operasinya secara atomik di dalam boundary-nya sendiri, memperbarui databasenya, lalu menerbitkan event atau message untuk memicu langkah berikutnya. Jika semua langkah berhasil, saga selesai. Jika salah satu langkah gagal, saga menjalankan compensating transactions untuk membatalkan transaksi pada langkah sebelumnya.
Berikut adalah tiga konsep penting yang dapat digunakan saat merancang saga:
- Compensable transaction: langkah yang bisa dibatalkan oleh aksi kompensasi.
- Pivot transaction: titik “point of no return”, yaitu batas setelahnya kompensasi tidak lagi relevan atau sifat operasi berubah menjadi tidak dapat di-undo.
- Retryable transaction: langkah setelah pivot yang harus bersifat idempotent dan dapat diulang sampai sistem mencapai keadaan final yang konsisten.
Konsep-konsep ini penting karena membantu kita memahami bahwa saga bukan hanya “if fail then refund”, tetapi sebuah workflow bisnis yang harus memikirkan langkah yang bisa dibatalkan, langkah yang tidak bisa dibatalkan, dan langkah yang aman untuk diulang.
Berikut adalah contoh diagram arsitektur saga (ilustrasi pada layanan Azure).

Pendekatan Implementasi Saga: Choreography dan Orchestration
Saga umumnya diimplementasikan dengan dua pendekatan utama:
- Choreography: setiap service menerbitkan event dan service lain merespons event tersebut tanpa pengendali pusat. Pendekatan ini cocok untuk workflow yang sederhana, tetapi dapat menjadi membingungkan ketika jumlah langkah dan layanan bertambah. Business flow dapat tersebar di banyak service sehingga lebih sulit diikuti.
- Orchestration: ada komponen terpusat, yaitu orchestrator, yang menyimpan state alur dan memberi tahu service lain apa yang harus dilakukan berikutnya. Pendekatan ini lebih cocok untuk workflow kompleks karena tanggung jawab koordinasi lebih jelas.
Saga Pattern adalah cara berpikir ulang tentang transaksi di dunia microservices. Alih-alih memaksa semua komponen ikut dalam satu transaksi global, kita memecah proses menjadi local transaction yang saling memicu lewat event atau command, lalu menyiapkan kompensasi jika salah satu langkah gagal.
Pada Part 2, kita akan masuk ke implementasi Choreography Saga: bagaimana OrderCreated, PaymentSucceeded, dan event-event lain membentuk workflow terdistribusi tanpa orchestrator pusat, serta apa saja yang perlu diperhatikan untuk implementasi di .NET dan Azure.
Leave a comment