Saya telah membaca tentang sumber acara akhir-akhir ini dan benar-benar menyukai ide di baliknya tetapi saya terjebak dengan masalah berikut.
Katakanlah Anda memiliki N proses bersamaan yang menerima perintah (misalnya server web), menghasilkan peristiwa sebagai hasilnya dan menyimpannya di toko terpusat. Mari kita juga berasumsi bahwa semua keadaan aplikasi sementara dipertahankan dalam memori proses individu dengan secara berurutan menerapkan peristiwa dari toko.
Sekarang, katakanlah kita memiliki aturan bisnis berikut: setiap pengguna yang berbeda harus memiliki nama pengguna yang unik.
Jika dua proses menerima perintah pendaftaran pengguna untuk nama pengguna X yang sama, mereka berdua memeriksa bahwa X tidak ada dalam daftar nama pengguna mereka, aturan memvalidasi untuk kedua proses dan mereka berdua menyimpan acara "pengguna baru dengan nama pengguna X" di toko .
Kami sekarang telah memasuki negara global yang tidak konsisten karena aturan bisnis dilanggar (ada dua pengguna berbeda dengan nama pengguna yang sama).
Dalam N server tradisional <-> 1 sistem gaya RDBMS, database digunakan sebagai titik sentral sinkronisasi yang membantu mencegah ketidakkonsistenan tersebut.
Pertanyaan saya adalah: bagaimana sistem bersumber peristiwa biasanya mendekati masalah ini? Apakah mereka hanya memproses setiap perintah secara berurutan (misalnya membatasi jumlah proses yang dapat menulis ke toko ke 1)?
sumber
Jawaban:
Dalam sistem bersumber acara, "toko acara" melayani peran yang sama. Untuk objek bersumber acara, tulisan Anda merupakan tambahan acara baru Anda ke versi tertentu dari aliran acara. Jadi, seperti halnya pemrograman bersamaan, Anda bisa memperoleh kunci pada riwayat itu saat memproses perintah. Ini lebih umum untuk sistem bersumber acara untuk mengambil pendekatan yang lebih optimis - memuat riwayat sebelumnya, menghitung riwayat baru, lalu membandingkan dan menukar. Jika beberapa perintah lain juga menulis ke aliran itu, maka perbandingan dan pertukaran Anda gagal. Dari sana, Anda menjalankan kembali perintah Anda, atau mengabaikan perintah Anda, atau mungkin bahkan menggabungkan hasil Anda ke dalam sejarah.
Pertarungan menjadi masalah besar jika semua server N dengan perintah M mereka mencoba menulis ke aliran tunggal. Jawaban yang biasa di sini adalah untuk mengalokasikan riwayat ke setiap entitas yang bersumber dari peristiwa dalam model Anda. Jadi Pengguna (Bob) akan memiliki riwayat yang berbeda dari Pengguna (Alice), dan menulis ke satu tidak akan memblokir menulis ke yang lain.
Greg Young di Set Validasi
Apakah ada cara yang elegan untuk memeriksa batasan unik pada atribut objek domain tanpa memindahkan logika bisnis ke lapisan layanan?
Jawaban singkat, dalam banyak kasus, menyelidiki persyaratan yang lebih dalam mengungkapkan bahwa (a) itu adalah proxy yang kurang dipahami untuk beberapa persyaratan lain, atau (b) bahwa pelanggaran terhadap "aturan" dapat diterima jika mereka dapat dideteksi (laporan pengecualian) , dimitigasi dalam jendela waktu tertentu, atau frekuensi rendah (mis .: klien dapat memeriksa apakah nama tersedia sebelum mengirim perintah untuk menggunakannya).
Dalam beberapa kasus, ketika toko acara Anda sangat bagus dalam menetapkan validasi (yaitu: database relasional), maka Anda menerapkan persyaratan dengan menulis ke tabel "nama unik" dalam transaksi yang sama yang tetap ada di acara tersebut.
Dalam beberapa kasus, Anda hanya dapat menegakkan persyaratan dengan meminta semua nama pengguna dipublikasikan ke aliran yang sama (yang memungkinkan Anda untuk mengevaluasi serangkaian nama dalam memori, sebagai bagian dari model domain Anda). - Dalam kasus ini, dua proses akan memperbarui upaya untuk memperbarui "aliran" sejarah, tetapi salah satu operasi perbandingan-dan-swap akan gagal, dan coba lagi perintah itu akan dapat mendeteksi konflik.
sumber
Sepertinya Anda dapat menerapkan proses bisnis (
saga
dalam konteksDomain Driven Design
) untuk pendaftaran pengguna di mana pengguna diperlakukan seperti aCRDT
.Sumber daya
https://doc.akka.io/docs/akka/current/distributed-data.html http://archive.is/t0QIx
"CRDT dengan Data Terdistribusi Akka" https://www.slideshare.net/markusjura/crdts-with-akka-distributed-data untuk mempelajari tentang
CmRDT
s - CRDT berbasis operasiCvRDT
s - sebutkan CRTD berbasis negaraContoh kode dalam Scala https://github.com/akka/akka-samples/tree/master/akka-sample-distributed-data-scala . Mungkin "keranjang belanja" paling cocok.
sumber