Pertimbangkan situs e-commerce, tempat Alice dan Bob mengedit daftar produk. Alice meningkatkan deskripsi, sementara Bob memperbarui harga. Mereka mulai mengedit Acme Wonder Widget secara bersamaan. Bob selesai lebih dulu dan menyimpan produk dengan harga baru. Alice membutuhkan waktu lebih lama untuk memperbarui deskripsi, dan ketika dia selesai, dia menyimpan produk dengan deskripsi barunya. Sayangnya, dia juga menimpa harga dengan harga lama, yang tidak dimaksudkan.
Dalam pengalaman saya, masalah ini sangat umum di aplikasi web. Beberapa perangkat lunak (mis. Perangkat lunak wiki) memang memiliki perlindungan terhadap ini - biasanya penyimpanan kedua gagal dengan "halaman diperbarui saat Anda mengedit". Tetapi sebagian besar situs web tidak memiliki perlindungan ini.
Perlu dicatat bahwa metode pengontrolnya aman untuk diri mereka sendiri. Biasanya mereka menggunakan transaksi basis data, yang membuat mereka aman dalam arti bahwa jika Alice dan Bob mencoba menyelamatkan pada saat yang sama, itu tidak akan menyebabkan korupsi. Kondisi balapan muncul dari Alice atau Bob yang memiliki data basi di browser mereka.
Bagaimana kita dapat mencegah kondisi balapan seperti itu? Secara khusus, saya ingin tahu:
- Teknik apa yang bisa digunakan? mis. melacak waktu perubahan terakhir. Apa pro dan kontra dari masing-masing.
- Apa pengalaman pengguna yang bermanfaat?
- Kerangka apa yang memiliki perlindungan ini dibangun?
sumber
Jawaban:
Anda perlu "membaca tulisan Anda", yang berarti sebelum Anda menuliskan perubahan, Anda perlu membaca catatan lagi dan memeriksa apakah ada perubahan di mana sejak Anda terakhir membacanya. Anda dapat melakukan bidang-per-bidang ini (berbutir halus) atau berdasarkan stempel waktu (berbutir kasar). Saat Anda melakukan pemeriksaan ini, Anda memerlukan kunci eksklusif pada catatan. Jika tidak ada perubahan yang dilakukan, Anda dapat menuliskan perubahan dan melepaskan kunci. Jika catatan telah berubah sementara itu, Anda membatalkan transaksi, lepaskan kunci dan beri tahu pengguna.
sumber
Saya telah melihat 2 cara utama:
Tambahkan stempel waktu pembaruan terakhir halaman yang sedang diedit dalam input tersembunyi. Ketika melakukan cap waktu diperiksa terhadap yang sekarang dan jika mereka tidak cocok itu telah diperbarui oleh orang lain dan mengembalikan kesalahan.
pro: banyak pengguna dapat mengedit bagian halaman yang berbeda. Halaman kesalahan dapat menyebabkan halaman berbeda di mana pengguna kedua dapat menggabungkan perubahannya di halaman baru.
con: kadang-kadang sebagian besar upaya terbuang sia-sia saat pengeditan besar-besaran.
Ketika seorang pengguna mulai mengedit halaman kunci untuk waktu yang wajar, ketika pengguna lain kemudian mencoba untuk mengedit dia mendapatkan halaman kesalahan dan harus menunggu sampai kunci berakhir atau pengguna pertama telah berkomitmen.
pro: sunting upaya tidak sia-sia.
con: pengguna yang tidak bermoral dapat mengunci halaman tanpa batas. Halaman dengan kunci kedaluwarsa mungkin masih dapat melakukan kecuali dinyatakan sebaliknya (menggunakan teknik 1)
sumber
Gunakan Kontrol Konkurensi Optimis .
Tambahkan kolom versionNumber atau versionTimestamp ke tabel yang dimaksud (integer paling aman).
Pengguna 1 membaca catatan:
Pengguna 2 membaca catatan:
Pengguna 1 menyimpan catatan, ini menambah versi:
Pengguna 2 mencoba untuk menyimpan catatan yang mereka baca:
Hibernate / JPA dapat melakukan ini secara otomatis dengan
@Version
anotasiAnda perlu mempertahankan status catatan baca di suatu tempat, umumnya dalam sesi (ini lebih aman daripada dalam variabel bentuk tersembunyi).
sumber
SQLAlchemy
tidak menunjukkan apa pun tentang kunci luring optimis, dan saya tidak dapat menemukannya di dokumen. Apakah Anda memiliki tautan yang lebih bermanfaat, atau hanya mengarahkan orang ke SQLAlchemy secara umum?Beberapa sistem Object Relational Mapping (ORM) akan mendeteksi bidang objek mana yang telah berubah sejak dimuat dari database, dan akan membangun pernyataan pembaruan SQL untuk hanya menetapkan nilai-nilai tersebut. ActiveRecord untuk Ruby on Rails adalah salah satu ORM tersebut.
Efek bersihnya adalah bahwa bidang yang tidak diubah pengguna tidak termasuk dalam perintah UPDATE yang dikirim ke database. Orang yang memperbarui bidang yang berbeda pada saat yang sama tidak saling menimpa perubahan.
Bergantung pada bahasa pemrograman yang Anda gunakan, teliti ORM mana yang tersedia, dan lihat apakah ada di antara mereka yang hanya akan memperbarui kolom dalam basis data bertanda "kotor" di aplikasi Anda.
sumber