Haruskah saya mengunci baris di DB cloud saya saat sedang diedit oleh pengguna

12

Saya membuat aplikasi desktop yang menyimpan data di cloud. Satu kekhawatiran yang saya miliki adalah mulai mengedit item dalam aplikasi dan membiarkannya sementara waktu menyebabkan data menjadi basi. Ini jelas dapat juga terjadi jika 2 orang mencoba mengedit item yang sama secara bersamaan. Ketika mereka selesai mengedit dan ingin menyimpan data, saya perlu menimpa apa yang saat ini ada di database atau memeriksa apakah mereka mulai mengedit setelah perubahan terakhir dan memaksa mereka untuk membuang perubahan mereka atau mungkin memberi mereka pilihan untuk mengambil risiko menimpa perubahan orang lain.

Saya berpikir tentang menambahkan bidang is_lockeddan lock_timestampke tabel DB. Ketika pengguna mulai mengedit item, baris akan berubah is_lockedmenjadi true dan mengatur cap waktu kunci ke waktu saat ini. Saya kemudian akan memiliki sejumlah waktu untuk mana kunci dipegang (mis. 5 menit). Jika ada orang lain yang mencoba mengedit item, mereka akan menerima pesan yang mengatakan item terkunci dan ketika kunci secara otomatis berakhir. Jika pengguna berjalan pergi saat mengedit kunci akan secara otomatis berakhir setelah periode waktu yang relatif singkat dan begitu itu dilakukan pengguna akan diperingatkan bahwa kunci telah kedaluwarsa dan dipaksa untuk memulai kembali edit setelah data di-refresh.

Apakah ini menjadi metode yang baik untuk mencegah menimpa data basi? Apakah ini berlebihan (saya tidak berharap aplikasi akan digunakan oleh lebih dari beberapa orang secara bersamaan pada satu akun).

(Kekhawatiran lain yang saya miliki adalah 2 orang mendapatkan kunci untuk item yang sama, namun saya percaya itu adalah kondisi lomba yang saya sukai.)

Yitzih
sumber
1
"Kekhawatiran lain yang saya miliki adalah 2 orang mendapatkan kunci untuk item yang sama, namun saya percaya itu adalah kondisi balapan yang membuat saya nyaman" - menggunakan transaksi basis data di sekitar perolehan kunci harus mencegah kondisi balapan tersebut.
Jules
Sebagian besar mesin basis data (dari jenis relasional, setidaknya) telah dibangun untuk mendukung hal ini. Ini adalah konsep yang sangat umum di dunia RDBMS, dan bahkan database "mainan" menanganinya dengan cukup baik, mengingat Anda mengatakan bahwa Anda menginginkan penguncian yang optimis atau pesimistis. Bagaimanapun, saya tidak berpikir itu adalah sesuatu yang Anda butuhkan untuk membangun diri Anda dengan cara apa pun: periksa opsi pada mesin db Anda untuk melihat bagaimana bekerja dengannya.
Jleach
Fakta bahwa aplikasi Anda adalah aplikasi desktop ( klien gemuk ) tidak membuat banyak perbedaan. Ini dapat dirancang dengan cara yang sama seperti aplikasi server multi-instance yang sangat tersedia.
Hosam Aly

Jawaban:

19

Satu hal yang akan membantu Anda di sini adalah terminologi. Apa yang Anda gambarkan di sini disebut 'penguncian pesimis'. Alternatif utama untuk pendekatan ini adalah 'penguncian optimis'. Dalam penguncian pesimistis, setiap aktor harus mengunci catatan sebelum memperbaruinya dan melepaskan kunci ketika pembaruan selesai. Dalam penguncian optimis, Anda menganggap bahwa tidak ada orang lain yang memperbarui catatan dan mencoba. Pembaruan gagal jika catatan diubah oleh beberapa aktor lain.

Penguncian yang optimis umumnya lebih disukai jika kemungkinan dua pelaku memperbarui hal yang sama pada saat yang sama rendah. Pesimistis biasanya digunakan ketika peluang itu tinggi atau Anda perlu tahu pembaruan Anda akan dapat berhasil sebelum Anda mulai. Dalam pengalaman saya, penguncian optimis hampir selalu lebih disukai karena ada banyak masalah yang melekat dalam penguncian pesimistis. Salah satu masalah terbesar disinggung dalam pertanyaan Anda. Pengguna dapat mengunci catatan untuk diedit dan kemudian pergi untuk makan siang. Mitigasi Anda akan membantu dengan itu tetapi pengalaman pengguna tidak akan lebih baik daripada pendekatan optimis dan kemungkinan akan jauh lebih buruk. Misalnya, satu pengguna membuka catatan, mulai memperbaruinya dan bos mereka muncul di meja mereka. Pengguna lain mencoba mengedit catatan. Terkunci. Pengguna kedua terus mencoba dan setelah 5 menit, kunci kedaluwarsa dan pengguna kedua memperbarui catatan. Pengguna pertama kembali ke layar, mencoba menyimpan dan diberitahu bahwa mereka kehilangan kunci. Sekarang dalam skenario yang sama dengan semuanya sama kecuali menggunakan penguncian optimis, pengalaman pengguna pertama hampir sama tetapi pengguna kedua tidak menunggu 5 menit.

Skema yang Anda layangkan akan sangat ditingkatkan dengan menerapkan penguncian optimis untuk nilai kunci tetapi firasat saya adalah bahwa penguncian optimis mungkin OK untuk semuanya dan Anda dapat menyingkirkan bidang is_locked.

Anda tidak memberikan 'cloud DB' apa yang Anda gunakan. Anda mungkin harus melihat fitur-fitur itu untuk melihat apakah ada fitur bawaan untuk ini sebelum menerapkan solusi Anda sendiri.

Inilah resep dasarnya: alih-alih bidang is_locked, miliki bidang nomor versi. Saat Anda mengambil catatan, Anda menarik versi catatan saat ini. Saat Anda memperbarui, Anda membuat pembaruan bergantung pada bidang versi yang cocok dengan apa yang Anda ambil dan menambahnya agar berhasil. Jika versi tidak cocok, pembaruan tidak berpengaruh dan Anda melaporkannya kembali sebagai kegagalan.

JimmyJames
sumber
Ini jawaban yang sangat membantu. Bisakah Anda jelaskan mengapa penguncian pesimistis tidak disarankan ketika ada kemungkinan kecil "tabrakan". Apakah ini murni karena mengharuskan pergi ke database untuk mulai mengedit, atau karena kompleksitas tambahan atau alasan lain? Terima kasih!
yitzih
3
@yitzih Beberapa menyarankan bacaan: Fowler et al, Pola Arsitektur Aplikasi Perusahaan . Ada seluruh bab tentang pertanyaan ini, dengan diskusi yang baik tentang semua opsi dan alasan untuk memilihnya.
Jules
2
@ Jimmy - Jawaban Anda baik-baik saja. Dalam beberapa kasus, melaporkan kesalahan kembali tidak cukup. Pertimbangkan kasus ketika pengguna menghabiskan beberapa menit memperbarui catatan. Dalam hal itu, gagal saja mungkin tidak cukup baik, orang mungkin ingin memberi pengguna kesempatan untuk menggabungkan perubahan penerbangan mereka dengan yang dilakukan oleh pengguna lain. Saya seharusnya mengatakan penguncian optimis mungkin memerlukan resolusi konflik tergantung pada kebutuhan Anda.
Jon Raynor
3
Perlu disebutkan bahwa penguncian pesimistis jauh lebih mudah untuk dijelaskan kepada klien. Jika Anda menulis pesan bahwa klien tidak dapat mengakses catatan karena saat ini sedang diedit oleh yang lain, klien sama-sama mengerti dan menerimanya secara umum. Jika Anda sebaliknya memberi tahu klien setelah menyimpan bahwa penyimpanan tidak mungkin karena sudah diperbarui oleh pengguna lain, 7/10, klien akan frustrasi dan / atau mengharapkan penjelasan untuk perilaku program aneh ini.
Neil
2
@ Neil Itu benar dan saya pikir itu sering mengapa penguncian pesimis digunakan ketika optimis lebih tepat. Seringkali alur kerja membuatnya sangat tidak mungkin bahwa ada tabrakan.
JimmyJames
0

Dari jawaban @ JimmyJames , kita dapat melihat bagaimana pertanyaannya sebenarnya tentang pengalaman pengguna .

Itu semua tergantung konteks. Berapa banyak waktu dan upaya yang diperlukan untuk memperbarui catatan? Seberapa sering beberapa pengguna ingin memperbarui dokumen yang sama?

Misalnya, jika pengguna Anda biasanya memerlukan beberapa detik untuk memperbarui catatan dan ada sedikit pertengkaran maka penguncian yang optimis mungkin adalah cara yang harus dilakukan. Paling buruk, pengguna harus menghabiskan beberapa detik lagi, mungkin hingga satu menit, untuk memperbarui dokumen.

Jika dokumen Anda sangat kontroversial tetapi terstruktur dengan baik, mungkin Anda dapat mengizinkannya mengunci masing-masing bidang dalam peningkatan 30 detik, menampilkan timer atau notifikasi yang tidak mencolok untuk memungkinkan mereka memperpanjang kunci.

Namun, jika pengguna Anda menghabiskan banyak waktu atau upaya maka Anda harus mempertimbangkan pendekatan lain. Apakah catatan Anda terstruktur dengan baik? Bisakah Anda memperlihatkan kepada pengguna perbandingan (perbedaan) antara versi di server dan versi yang mereka coba simpan? Bisakah Anda menyoroti perbedaannya? Bisakah Anda membiarkan mereka menggabungkan perubahan? Pikirkan pengalaman yang ingin Anda miliki dengan alat kontrol sumber Anda. Anda benar-benar tidak ingin dipaksa untuk menulis semua kode itu lagi!

Anda dapat melihat Google Documents untuk inspirasi tambahan. Mungkin Anda bisa menunjukkan kepada pengguna pemberitahuan bahwa versi baru telah disimpan. Mungkin Anda dapat menunjukkan kepada mereka berapa banyak orang yang memiliki catatan terbuka sehingga mereka dapat memilih untuk kembali pada waktu yang tidak terlalu kontroversial.

Hosam Aly
sumber