Pertanyaan Bagaimana cara memastikan Atomicity Operasi RMI?


Saya ingin memperbarui file menggunakan RMI. Bagaimana saya dapat memastikan status operasi.

Klien terhubung ke server dan memanggil metode. Setelah itu, koneksi antara klien dan server rusak dan klien mendapatkan RemoteException, tetapi metode yang disebut terus bekerja dan mengubah file kemudian kembali dan mendapatkan pengecualian (Dengan asumsi itu akan menyadari koneksi yang hilang ketika menulis respon ke soket).


4
2018-01-04 13:20


asal


Jawaban:


Ini cukup rumit untuk dilakukan dalam praktek. Anda perlu mengimplementasikan protokol commit dua fase, di mana klien bisa mendapatkan indikator bahwa server dapat menjamin komit, kemudian memesan commit.

Ada sebuah protokol luar-sebut yang disebut XA untuk mengelola proses ini, dan ini didukung oleh Java Transaction API. Pada dasarnya Anda bisa membangun sebuah XA resource manager yang kompatibel untuk file Anda.

Ini bukan pekerjaan sepele tetapi tidak di luar batas kemungkinan jika Anda tidak keberatan termasuk server aplikasi atau manajer transaksi di infrastruktur Anda. Keuntungan dari pendekatan ini adalah Anda dapat menghubungkan ke dalam infrastruktur manajemen transaksi yang sudah tua dan terbebani.

Beberapa alternatif adalah:

  • Menerapkan protokol commit dua fase Anda sendiri, atau

  • Struktur file yang memperbarui kode yang bersifat idempoten (beberapa panggilan untuk membuat pembaruan yang sama hanya membuat pembaruan itu). Dalam hal ini Anda dapat mencoba kembali pembaruan hingga klien Anda mendapatkan indikator keberhasilan dari server.

    Perhatikan bahwa Anda juga harus datang dengan protokol untuk mengunci dan / atau mengelola pembaruan yang saling bertentangan pada catatan yang sama kecuali Anda dapat menjamin penulisan sekuensial dari klien. Tergantung pada aplikasi Anda ini mungkin bisa menjadi protokol konkurensi yang optimis tetapi Anda masih harus mengunci rentang yang sedang Anda kerjakan saat mengoperasikannya untuk membuat atom menulis.


5
2018-01-04 13:40



Anda sedang berurusan dengan pemrosesan terdistribusi. Ini berarti kamu tidak bisa menjamin bahwa pesan tertentu (panggilan metode, dll.) akan tiba di ujung yang lain; koneksi dapat selalu diturunkan secara sewenang-wenang. Karena itu, Anda memerlukan strategi mitigasi yang tidak bergantung pada pesan tertentu yang datang.

Salah satu strategi tersebut adalah dengan menggunakan sistem pesan yang andal, yang pada dasarnya menempatkan database untuk menahan antrean pesan yang kemudian dikirimkan secara andal dalam urutan (dengan mengirim pesan - ditandai dengan pengidentifikasi urutan - berulang kali sampai pengakuan diterima), tetapi ini adalah banyak overhead, dan mungkin harus disimpan untuk hal-hal penting (misalnya, transaksi keuangan).

Strategi lain adalah menggunakan manajer transaksi terdistribusi, tetapi mereka memiliki masalah yang cukup besar (kecuali Anda menerapkan sistem konsensus terdistribusi, dan itu kompleks dan masih memiliki mode kegagalan potensial).

Saya pikir cara paling sederhana adalah mengatur kembali apa yang dianggap pasti. Minta klien berkomunikasi dengan server untuk merakit sementara deskripsi operasi yang akan dilakukan pada server (termasuk id unik, misalnya UUID), maka klien dapat mengirim pesan singkat yang memulai commit; pada saat itu server perlu mencatat bahwa itu mulai bekerja pada proses UUID itu. Jika respons tidak dapat dikirim, itu masih setelah komit. Jika ada pesan yang hilang, itu bukan masalah besar: baik sebelum komit dimulai (dalam hal ini tidak terjadi dan dapat dicoba ulang) atau setelah itu akan ada rekaman permanen bahwa telah dicoba dan mudah untuk melaporkan apa yang terjadi (“Saya masih mengerjakannya”, “Saya berhasil”, “saya telah gagal”). Satu-satunya keadaan yang perlu diingat oleh klien adalah UUID, dan yang dapat dialokasikan di luar transaksi (properti indah UUID yang diakui hanya benar secara probabilistik, tetapi kemungkinan masalah benar-benar dapat diabaikan).


0
2018-01-04 14:00



Anda dapat mengirimkan argumen counter berurutan dari klien ke server dengan setiap operasi. Tergantung pada apa skenario penggunaan Anda, server Anda perlu mengingat satu atau lebih dari penghitung terbaru yang dikirim. jika nilai yang terlihat telah terjadi, Anda dapat mengembalikan kesuksesan (atau apa pun). Jika nilai-nilai harus unik di beberapa klien, Anda bisa menggunakan sesuatu seperti UUID (disebutkan oleh jawaban lain). Banyak dari ini tergantung pada apa nilai kembali dan apa urutan panggilan tampak seperti.

sebagai contoh, saya menerapkan ide ini di rmiio proyek untuk menangani masalah ini. di perpustakaan rmiio, Anda hanya perlu menghadapi kemungkinan operasi "saat ini" sedang diulang, jadi Anda hanya perlu melacak nilai counter terakhir.


0
2018-01-04 14:02



Jika Anda memilih untuk menggulung sistem pseudo-transaksi Anda sendiri, inilah dasarnya:

Di sisi server:

  • Lakukan panggilan balik dari server ke klien untuk mengumumkan bahwa Anda siap untuk menulis file. Jika ini memberi kesalahan, batalkan prosedur.
  • Hanya jika callback berhasil, sebenarnya menulis file.

Di klien:

  • Ketika Anda mendapatkan RemoteException, periksa apakah callback telah dijalankan atau tidak.
  • Jika callback dieksekusi, Anda bisa menjadi 'sangat yakin' bahwa sisa prosedur akan dijalankan, dan RemoteException terjadi karena beberapa alasan lain.

0
2018-01-04 14:04