Saya mengerti perbedaan antara penguncian optimis dan pesimistis. Sekarang bisakah seseorang menjelaskan kepada saya kapan saya akan menggunakan salah satu dari mereka secara umum?
Dan apakah jawaban untuk pertanyaan ini berubah tergantung pada apakah saya menggunakan prosedur tersimpan atau tidak untuk melakukan kueri?
Tetapi hanya untuk memeriksa, optimis berarti "jangan mengunci meja saat membaca" dan pesimistis berarti "mengunci meja saat membaca."
sql-server
locking
optimistic-locking
pessimistic-locking
Jason Baker
sumber
sumber
At any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts
.Jawaban:
Penguncian Optimis adalah strategi di mana Anda membaca catatan, mencatat nomor versi (metode lain untuk melakukan ini melibatkan tanggal, cap waktu atau checksum / hashes) dan memeriksa bahwa versi tidak berubah sebelum Anda menulis catatan kembali. Saat Anda menulis catatan kembali, Anda memfilter pembaruan pada versi untuk memastikan itu atom. (Yaitu belum diperbarui antara saat Anda memeriksa versi dan menulis catatan ke disk) dan memperbarui versi dalam satu pukulan.
Jika catatan kotor (yaitu versi berbeda dengan milik Anda), Anda membatalkan transaksi dan pengguna dapat memulai kembali.
Strategi ini paling berlaku untuk sistem volume tinggi dan arsitektur tiga tingkat di mana Anda tidak perlu menjaga koneksi ke database untuk sesi Anda. Dalam situasi ini klien tidak dapat benar-benar menjaga kunci basis data karena koneksi diambil dari kumpulan dan Anda mungkin tidak menggunakan koneksi yang sama dari satu akses ke yang berikutnya.
Penguncian Pesimis adalah ketika Anda mengunci catatan untuk penggunaan eksklusif Anda sampai Anda selesai dengan itu. Ini memiliki integritas yang jauh lebih baik daripada penguncian optimis tetapi mengharuskan Anda untuk berhati-hati dengan desain aplikasi Anda untuk menghindari Deadlock . Untuk menggunakan penguncian pesimistis Anda memerlukan koneksi langsung ke basis data (seperti yang biasanya terjadi pada aplikasi server klien dua tingkat ) atau ID transaksi yang tersedia secara eksternal yang dapat digunakan secara terpisah dari koneksi.
Dalam kasus terakhir Anda membuka transaksi dengan TxID dan kemudian menyambung kembali menggunakan ID itu. DBMS mempertahankan kunci dan memungkinkan Anda untuk mengambil kembali sesi melalui TxID. Ini adalah cara transaksi terdistribusi menggunakan protokol komit dua fase (seperti XA atau COM + Transaksi ) bekerja.
sumber
Penguncian optimis digunakan ketika Anda tidak mengharapkan banyak tabrakan. Biayanya lebih rendah untuk melakukan operasi normal tetapi jika tabrakan terjadi, Anda akan membayar harga yang lebih tinggi untuk menyelesaikannya karena transaksi dibatalkan.
Penguncian pesimis digunakan ketika tabrakan diantisipasi. Transaksi yang akan melanggar sinkronisasi hanya diblokir.
Untuk memilih mekanisme penguncian yang tepat, Anda harus memperkirakan jumlah bacaan dan tulisan dan rencanakan dengan tepat.
sumber
Optimis berasumsi bahwa tidak ada yang akan berubah saat Anda membacanya.
Pesimistis mengasumsikan bahwa sesuatu akan dan akan menguncinya.
Jika tidak penting data dibaca dengan sempurna, gunakan optimis. Anda mungkin membaca 'kotor' yang aneh - tetapi jauh lebih kecil kemungkinannya menghasilkan kebuntuan dan sejenisnya.
Sebagian besar aplikasi web baik-baik saja dengan pembacaan yang kotor - pada kesempatan yang jarang, data tidak persis sesuai dengan penghitungan ulang berikutnya.
Untuk operasi data yang tepat (seperti dalam banyak transaksi keuangan) gunakan pesimistis. Sangat penting bahwa data dibaca secara akurat, tanpa perubahan yang tidak ditampilkan - overhead penguncian ekstra sepadan.
Oh, dan Microsoft SQL server default untuk penguncian halaman - pada dasarnya baris yang Anda baca dan beberapa sisi. Penguncian baris lebih akurat tetapi jauh lebih lambat. Seringkali ada baiknya Anda mengatur transaksi Anda menjadi read-commit atau no-lock untuk menghindari kebuntuan saat membaca.
sumber
Selain apa yang sudah dikatakan:
optimistic
penguncian cenderung meningkatkan konkurensi dengan mengorbankan prediktabilitas.Pessimistic
mengunci cenderung mengurangi konkurensi, tetapi lebih dapat diprediksi. Anda membayar uang Anda, dll ...sumber
Saat menangani konflik, Anda memiliki dua opsi:
Sekarang, mari kita pertimbangkan anomali Pembaruan Hilang berikut :
Anomali Pembaruan yang Hilang dapat terjadi di tingkat isolasi Komitmen Baca .
Dalam diagram di atas kita dapat melihat bahwa Alice yakin dia dapat menarik 40 darinya
account
tetapi tidak menyadari bahwa Bob baru saja mengubah saldo akun, dan sekarang hanya ada 20 yang tersisa di akun ini.Mengunci Pesimistis
Penguncian pesimistis mencapai sasaran ini dengan mengambil kunci yang dibagikan atau dibaca di akun sehingga Bob tidak dapat mengubah akun.
Dalam diagram di atas, baik Alice dan Bob akan mendapatkan kunci baca di
account
baris tabel yang telah dibaca oleh kedua pengguna. Database memperoleh kunci ini pada SQL Server saat menggunakan Baca berulang atau Serializable.Karena baik Alice dan Bob telah membaca
account
dengan nilai PK1
, tidak satu pun dari mereka dapat mengubahnya sampai satu pengguna melepaskan kunci baca. Ini karena operasi penulisan memerlukan akuisisi kunci tulis / eksklusif, dan kunci bersama / baca mencegah kunci tulis / eksklusif.Hanya setelah Alice melakukan transaksi dan kunci baca dirilis di
account
baris, BobUPDATE
akan melanjutkan dan menerapkan perubahan. Sampai Alice melepaskan kunci baca, UPDATE Bob memblokir.Penguncian Optimis
Penguncian yang Optimis memungkinkan terjadinya konflik tetapi mendeteksinya setelah menerapkan UPDATE Alice karena versinya telah berubah.
Kali ini, kami memiliki
version
kolom tambahan . Theversion
kolom bertambah setiap kali UPDATE atau DELETE dijalankan, dan juga digunakan dalam klausa WHERE dari UPDATE dan pernyataan DELETE. Agar ini berfungsi, kita perlu mengeluarkan SELECT dan membaca saat iniversion
sebelum menjalankan UPDATE atau DELETE, karena jika tidak, kita tidak akan tahu nilai versi apa yang diteruskan ke klausa WHERE atau kenaikan.Transaksi tingkat aplikasi
Sistem basis data relasional telah muncul di akhir tahun 80-an awal 80-an ketika seorang klien, biasanya, terhubung ke mainframe melalui terminal. Itu sebabnya kami masih melihat sistem basis data mendefinisikan istilah seperti pengaturan SESI.
Saat ini, melalui Internet, kami tidak lagi menjalankan membaca dan menulis dalam konteks transaksi basis data yang sama, dan ACID tidak lagi memadai.
Misalnya, pertimbangkan use case berikut:
Tanpa penguncian yang optimis, Lost Update ini tidak mungkin tertangkap bahkan jika transaksi basis data yang digunakan Serializable. Ini karena membaca dan menulis dieksekusi dalam permintaan HTTP yang terpisah, karenanya pada transaksi basis data yang berbeda.
Jadi, penguncian yang optimis dapat membantu Anda mencegah Pembaruan yang Hilang bahkan ketika menggunakan transaksi tingkat aplikasi yang juga memasukkan waktu berpikir pengguna.
Kesimpulan
Penguncian optimis adalah teknik yang sangat berguna, dan berfungsi dengan baik bahkan ketika menggunakan tingkat isolasi yang kurang ketat, seperti Read Committed, atau ketika membaca dan menulis dieksekusi dalam transaksi basis data berikutnya.
Kelemahan dari penguncian optimis adalah bahwa kemunduran akan dipicu oleh kerangka kerja akses data setelah menangkap
OptimisticLockException
, karena itu kehilangan semua pekerjaan yang telah kami lakukan sebelumnya oleh transaksi yang sedang berjalan.Semakin banyak pertikaian, semakin banyak konflik, dan semakin besar peluang untuk membatalkan transaksi. Kembalikan dapat mahal untuk sistem database karena perlu mengembalikan semua perubahan yang tertunda saat ini yang mungkin melibatkan baris tabel dan catatan indeks.
Karena alasan ini, penguncian pesimistis mungkin cocok untuk saat konflik sering terjadi, karena hal ini mengurangi peluang untuk memutar kembali transaksi.
sumber
PESSIMISTIC_FORCE_INCREMENT
.Saya akan memikirkan satu lagi kasus ketika penguncian pesimistis akan menjadi pilihan yang lebih baik.
Untuk penguncian yang optimis setiap peserta dalam modifikasi data harus setuju dalam menggunakan penguncian semacam ini. Tetapi jika seseorang memodifikasi data tanpa memperhatikan kolom versi, ini akan merusak seluruh gagasan penguncian optimis.
sumber
Pada dasarnya ada dua jawaban paling populer. Yang pertama pada dasarnya mengatakan
Jawaban lain adalah
atau
Seperti yang ada di halaman ini.
Saya membuat jawaban saya untuk menjelaskan bagaimana "menjaga koneksi" terkait dengan "tabrakan rendah".
Untuk memahami strategi mana yang terbaik untuk Anda, jangan pikirkan tentang Transaksi Per Detik yang dimiliki DB Anda tetapi durasi satu transaksi. Biasanya, Anda membuka transaksi, operasi kinerja dan menutup transaksi. Ini adalah transaksi singkat dan klasik yang ada dalam pikiran ANSI dan tidak masalah untuk mengunci. Tetapi, bagaimana Anda menerapkan sistem reservasi tiket di mana banyak klien memesan kamar / kursi yang sama secara bersamaan?
Anda menelusuri penawaran, mengisi formulir dengan banyak opsi yang tersedia dan harga saat ini. Dibutuhkan banyak waktu dan opsi menjadi usang, semua harga tidak valid di antara Anda mulai mengisi formulir dan tekan tombol "Saya setuju" karena tidak ada kunci pada data yang telah Anda akses dan orang lain, yang lebih gesit, telah tertarik mengubah semua harga dan Anda harus memulai kembali dengan harga baru.
Anda bisa mengunci semua opsi saat membacanya. Ini adalah skenario pesimistis. Anda tahu mengapa itu menyebalkan. Sistem Anda dapat dihancurkan oleh satu badut yang baru saja memulai reservasi dan mulai merokok. Tidak ada yang bisa memesan apa pun sebelum dia selesai. Arus kas Anda turun ke nol. Itu sebabnya, pemesanan optimis digunakan dalam kenyataan. Mereka yang terlalu lama harus memulai kembali reservasi mereka dengan harga yang lebih tinggi.
Dalam pendekatan optimis ini Anda harus mencatat semua data yang Anda baca (seperti dalam Repeat Read yang saya baca ) dan sampai pada titik komit dengan versi data Anda (saya ingin membeli saham pada harga yang Anda tampilkan dalam kutipan ini, bukan harga saat ini ). Pada titik ini, transaksi ANSI dibuat, yang mengunci DB, memeriksa apakah tidak ada yang berubah dan melakukan / membatalkan operasi Anda. IMO, ini adalah emulasi efektif dari MVCC , yang juga terkait dengan Optimistic CC dan juga mengasumsikan bahwa transaksi Anda dimulai kembali jika dibatalkan, yaitu Anda akan membuat reservasi baru. Transaksi di sini melibatkan keputusan pengguna manusia.
Saya jauh dari memahami bagaimana mengimplementasikan MVCC secara manual, tetapi saya pikir transaksi jangka panjang dengan opsi restart adalah kunci untuk memahami subjek. Koreksi saya jika saya salah di mana saja. Jawaban saya termotivasi oleh bab Alex Kuznecov ini .
sumber
Dalam kebanyakan kasus, penguncian optimis lebih efisien dan menawarkan kinerja yang lebih tinggi. Saat memilih antara penguncian pesimis dan optimis, pertimbangkan hal berikut:
Penguncian pesimis berguna jika ada banyak pembaruan dan peluang yang relatif tinggi dari pengguna yang mencoba memperbarui data pada saat yang sama. Misalnya, jika setiap operasi dapat memperbarui sejumlah besar catatan pada satu waktu (bank mungkin menambahkan pendapatan bunga ke setiap akun pada akhir setiap bulan), dan dua aplikasi menjalankan operasi tersebut pada saat yang sama, mereka akan mengalami konflik .
Penguncian pesimistis juga lebih tepat dalam aplikasi yang berisi tabel kecil yang sering diperbarui. Dalam kasus yang disebut hotspot ini, konflik sangat mungkin terjadi sehingga upaya penguncian yang sia-sia akan sia-sia dalam mengembalikan transaksi yang saling bertentangan.
Penguncian optimis berguna jika kemungkinan konflik sangat rendah - ada banyak catatan tetapi relatif sedikit pengguna, atau sangat sedikit pembaruan dan sebagian besar operasi tipe-baca.
sumber
Satu kasus penggunaan untuk penguncian optimis adalah membuat aplikasi Anda menggunakan database untuk memungkinkan salah satu utas / host Anda 'mengklaim' suatu tugas. Ini adalah teknik yang berguna bagi saya secara teratur.
Contoh terbaik yang dapat saya pikirkan adalah untuk antrian tugas yang diimplementasikan menggunakan database, dengan beberapa utas mengklaim tugas secara bersamaan. Jika tugas memiliki status 'Tersedia', 'Diklaim', 'Selesai', permintaan db dapat mengatakan sesuatu seperti "Set status = 'Diklaim' di mana status = 'Tersedia'. Jika beberapa utas mencoba mengubah status dengan cara ini, semua kecuali utas pertama akan gagal karena data kotor.
Perhatikan bahwa ini adalah use case yang hanya melibatkan penguncian optimis. Jadi sebagai alternatif untuk mengatakan "Penguncian optimis digunakan ketika Anda tidak mengharapkan banyak tabrakan", itu juga dapat digunakan di mana Anda mengharapkan tabrakan tetapi ingin tepat satu transaksi berhasil.
sumber
Banyak hal baik telah dikatakan di atas tentang penguncian optimis dan pesimis. Satu poin penting untuk dipertimbangkan adalah sebagai berikut:
Saat menggunakan penguncian yang optimis, kita perlu berhati-hati terhadap kenyataan bahwa bagaimana aplikasi akan pulih dari kegagalan ini.
Khususnya dalam arsitektur yang didorong pesan asinkron, ini dapat menyebabkan pemrosesan pesan yang tidak sesuai atau pembaruan yang hilang.
Skenario kegagalan perlu dipikirkan.
sumber