Kolom Tekno

Race Condition di Arsitektur Event-Driven: Tim Temukan Solusi Dual-Layer untuk Duplikasi Webhook

Ringkasan

  • Tim engineering mengatasi kerentanan race condition akibat duplikasi webhook di arsitektur berbasis Kafka dengan menerapkan pola Idempotent Consumer menggunakan Redis dan constraint database.

Masalah duplikasi pesan di arsitektur event-driven bukan hal baru, namun tim pengembang baru-baru ini menemukan celah kritis yang meloloskan ribuan webhook ganda melewati validasi aplikasi. Insiden ini terjadi saat tim melakukan pembaruan sistem produksi besar-besaran, di mana arsitektur berbasis antrian pesan seperti Kafka seharusnya menjamin skalabilitas tinggi. Kebenarannya, jaminan at-least-once delivery yang ditawarkan broker enterprise justru menjadi bumerang saat validasi level aplikasi gagal menangani eksekusi konkuren.

Inti masalah terletak pada race condition halus yang muncul ketika dua event identik tiba di node API berbeda hanya berjarak milidetik. Karena beban kerja tersebar di beberapa instance container, kedua node menjalankan validasi database pada saat yang bersamaan. Keduanya mendeteksi data belum ada, keduanya lolos validasi, dan keduanya menulis ke database — menciptakan inkonsistensi data yang sulit dilacak. Lapisan pertahanan aplikasi yang dikira cukup justru tidak berdaya menghadapi permintaan konkuren.

Latar belakang teknisnya mengacu pada karakteristik fundamental message broker modern. Kafka, RabbitMQ, maupun Pulsar dirancang dengan prioritas pada throughput dan ketersediaan, bukan keunikan pesan. Jika partisi jaringan terjadi atau konsumen gagal mengirim acknowledgment tepat waktu, broker akan mengirim ulang pesan. Di sistem pembayaran atau inventaris, duplikasi ini berarti transaksi ganda atau stok negatif — kerugian finansial nyata yang tidak bisa ditoleransi.

Solusi yang diterapkan tim mengadopsi pola Idempotent Consumer dengan pendekatan dua lapisan yang saling melengkapi. Lapisan pertama menggunakan Redis sebagai distributed lock melalui perintah atomik SETNX (Set if Not Exists) dengan TTL 30 detik. Setiap worker harus memperoleh kunci unik berbasis event_id sebelum memproses event. Jika duplikat tiba di worker lain saat worker pertama masih memproses, worker kedua gagal mendapatkan lock dan keluar dengan lembut tanpa menyentuh data primer.

Redis menangani 99 persen kasus duplikasi, namun jaringan terdistribusi selalu menyimpan kemungkinan kegagalan parsial. Failover cluster Redis atau kehilangan paket bisa menciptakan celah bagi duplikat yang lolos. Oleh karena itu, lapisan kedua ditempatkan di database relasional inti: tabel idempotency_keys dengan Unique Constraint pada kolom key_hash. Setiap worker yang memperbarui logika bisnis wajib menulis hash event ke tabel ini di dalam blok transaksi database yang persis sama.

Mekanisme transaksi atomik ini menjadi benteng terakhir. Worker membuka transaksi, memperbarui data bisnis, memasukkan hash event, lalu commit. Jika duplikat lolos Redis, mesin database akan menolak insert hash ganda, melempar UniqueConstraintViolationException, dan memaksa rollback atomik seluruh transaksi. Tidak ada data parsial yang tertulis, tidak ada inkonsistensi yang tersisa.

Uji beban dengan 10.000 permintaan duplikat konkuren per detik membuktikan efektivitas arsitektur ini. Sistem mencapai 100 persen konsistensi data dengan overhead performa yang dapat diabaikan. Pola ini kini menjadi referensi internal untuk semua layanan kritis yang mengonsumsi event dari message broker.

Bagi industri teknologi Indonesia, pelajaran ini sangat relevan seiring maraknya adopsi microservices dan arsitektur event-driven di perusahaan fintech, e-commerce, hingga platform logistik. Banyak tim lokal mengandalkan validasi level aplikasi semata — misalnya cek status transaksi sebelum update — tanpa memperhitungkan eksekusi paralel di lingkungan Kubernetes atau serverless. Kekhawatiran biaya infrastruktur tambahan untuk Redis sering jadi alasan penolakan, padahal kerugian data tidak konsisten jauh lebih mahal.

Beberapa startup Indonesia sudah mulai menerapkan pola serupa. Platform pembayaran digital terkemuka di Jakarta melaporkan pengurangan 99,8 persen insiden duplikasi transaksi setelah memasang idempotency key di layer database. Perusahaan logistik berbasis Jakarta juga mengadopsi Redis SETNX untuk mengunci proses update status pengiriman, menghindari status ganda yang membingungkan kurir dan pelanggan.

Kendati demikian, tantangan implementasi di skala enterprise Indonesia tetap ada. Latensi jaringan antar availability zone di cloud provider lokal bisa mempengaruhi performa Redis lock. Beberapa tim memilih memindahkan logika locking ke database sepenuhnya menggunakan SELECT FOR UPDATE, mengorbankan throughput demi kesederhanaan arsitektur. Pilihan arsitektur harus disesuaikan dengan profil beban kerja dan toleransi risiko masing-masing organisasi.

Ke depan, pola idempotensi akan menjadi prasyarat standar bukan sekadar best practice. Standar seperti CloudEvents sudah mulai mendorong idempotency key sebagai bagian dari spesifikasi event. Tim platform di Indonesia sebaiknya mulai membangun library internal yang mengabstraksi dua lapisan pertahanan ini, sehingga developer produk tidak perlu menulis ulang logika locking dan constraint di setiap layanan baru.

Mengapa Ini Penting

Artikel ini mengungkap celah fundamental yang sering terlewat tim Indonesia saat membangun sistem berbasis event: validasi aplikasi tidak cukup untuk menangani konkuren di lingkungan terdistribusi. Pendekatan dual-layer Redis + database constraint menawarkan solusi praktis yang sudah terbukti di skala produksi tinggi. Bagi CTO dan arsitek lokal, ini jadi bukti nyata bahwa investasi infrastruktur idempotensi lebih murah dari biaya recovery data korup. Tren regulasi keuangan digital di Indonesia yang semakin ketat soal akurasi transaksi membuat pola ini hampir wajib diadopsi.

Sumber Asli
Dev.to
Tanggal
14 Juli 2026
Waktu Baca
5 menit