Apa hubungan yang tepat antara transaksi basis data dan penguncian?

16

Ini adalah pertanyaan sederhana yang diajukan dalam semangat meningkatkan pengetahuan saya; mohon bersikap lembut dalam tanggapan Anda.

Sebagai pengembang aplikasi lama, saya tahu pada tingkat tertentu apa transaksi itu (saya menggunakannya sepanjang waktu). Mengesampingkan tingkat isolasi transaksi untuk saat ini, pada tingkat tinggi transaksi memungkinkan blok pekerjaan diselesaikan seluruhnya atau tidak sama sekali, dan memungkinkan sejumlah isolasi dari aktivitas pengubah basis data lainnya.

Saya juga tahu apa (dalam berbagai database) kunci adalah, atau setidaknya bagaimana seseorang berperilaku (jika saya mengunci tabel dengan cara tertentu secara eksplisit, maka tidak ada proses atau utas lain yang dapat memperbarui apa pun tentang tabel itu).

Yang paling jelas saya tidak jelas tentang adalah: dalam berbagai database, ketika saya secara eksplisit mengunci baris atau tabel, apakah saya menggunakan konstruksi yang sama persis yang digunakan oleh fasilitas transaksi database di bawah selimut untuk membuat transaksi berfungsi dengan baik?

Yaitu, terpikir oleh saya bahwa agar suatu transaksi bersifat atomik dan terisolasi, ia harus melakukan penguncian. Apakah transaksi ini diprakarsai, penguncian yang tersembunyi penguncian dengan jenis penguncian yang sama yang memungkinkan saya mengakses berbagai basis data melalui konstruksi seperti SELECT FOR UPDATEatau LOCKperintah eksplisit ? Atau apakah kedua konsep ini sangat berbeda?

Sekali lagi, saya minta maaf atas ketelanjangan pertanyaan ini; Saya senang bisa diarahkan ke sumber yang lebih mendasar.

Laird Nelson
sumber

Jawaban:

12

ketika saya secara eksplisit mengunci baris atau tabel, apakah saya menggunakan konstruksi yang sama persis yang digunakan oleh fasilitas transaksi database di bawah selimut untuk membuat transaksi berfungsi dengan baik?

Iya. Jika itu tidak benar, maka 'penguncian' Anda sendiri hanya akan mencakup untuk 'penguncian' serupa lainnya dan tidak berinteraksi dengan penguncian mesin itu sendiri. Jadi Anda akan mengunci baris dalam sebuah tabel sehingga tidak dapat dikunci oleh aplikasi lain dengan cara yang sama, tetapi kunci Anda akan diabaikan oleh mesin itu sendiri. Semantik ini jarang diinginkan. Sebagian besar waktu aplikasi mengunci baris berarti 'menguncinya terhadap segala cara akses / modifikasi'. Catatan: mekanisme penguncian yang khusus untuk aplikasi memang ada, karena mereka berguna. Misalnya SQL Server memiliki kunci aplikasi .

terpikir olehku bahwa agar suatu transaksi bersifat atomik dan terisolasi, ia harus melakukan penguncian.

Mengunci adalah salah satu cara untuk mencapai ini. Alternatif utama adalah versi. Saat ini sebagian besar database mendukung keduanya (yang juga berarti bahwa jika Anda 'mengunci' sebuah baris di dalam aplikasi tetapi transaksi lain menggunakan versi untuk membaca baris, itu akan membacanya karena penguncian Anda tidak memblokir bacaan berversi).

Anda semacam berputar-putar di sekitar konsep yang dikenal di dunia implementasi basis data sebagai 'protokol penguncian dua fase' . artikel Wikipedia yang terhubung adalah awal yang baik. Jika Anda ingin membaca penjelasan lebih rinci tentang topik ini, saya sarankan Anda pergi ke perpustakaan dan meminta pinjaman untuk Pemrosesan Transaksi: Konsep dan Teknik . Hampir setiap database di luar sana, pada intinya, merupakan implementasi dari buku itu.

Remus Rusanu
sumber
Mungkin Anda dapat menambahkan tentang kontrol konkurensi optimis
ypercubeᵀᴹ
Aha! Sekarang kita bicara. Memang, yang bersembunyi di benakku adalah MVCC . Terima kasih atas jawaban yang diartikulasikan dengan baik, referensi yang bagus dan untuk meluangkan waktu untuk benar-benar menggali pertanyaan saya.
Laird Nelson
3

Beberapa latar belakang sebelum menjawab pertanyaan Anda:

Catatan: Ini terkait dengan Microsoft SQL Server - RDBMS ........

  • Dalam istilah yang sangat sederhana, transaksi adalah urutan pekerjaan yang harus dilakukan sebagai unit logis tunggal secara keseluruhan dan harus mempertahankan properti ACID.
  • Setiap RDBMS harus menyediakan "Fasilitas penguncian" yang dapat digunakan untuk menyelesaikan transaksi secara keseluruhan, di sana dengan menjaga isolasi transaksi dan daya tahannya. Ini memastikan integritas fisik dari database.
  • Yang paling penting, secara default - transaksi dikelola pada tingkat koneksi. Jadi ketika transaksi dimulai pada koneksi, semua pernyataan T-SQL (S / I / U / D) yang dieksekusi pada koneksi itu adalah bagian dari transaksi sampai transaksi berakhir. ( MARS ditangani secara berbeda)

Sekarang kembali ke pertanyaan Anda:

ketika saya secara eksplisit mengunci baris atau tabel, apakah saya menggunakan konstruksi yang sama persis yang digunakan oleh fasilitas transaksi database di bawah selimut untuk membuat transaksi berfungsi dengan baik?

Iya. Ini berarti bahwa Anda harus berhati-hati dalam menentukan urutan data yang akan dimodifikasi dan yang akan membuat database konsisten. Dengan kata lain, operasi DML Anda harus meninggalkan database dalam keadaan konsisten yang membatasi aturan bisnis organisasi Anda. Namun, RDBMS (di sini SQL Server) dapat menegakkan integritas fisik transaksi.

Dari BOL: Penguncian dan pembuatan versi baris mencegah pengguna membaca data yang tidak dikomit dan mencegah beberapa pengguna mencoba mengubah data yang sama pada saat yang bersamaan. Tanpa penguncian atau versi baris, kueri yang dieksekusi terhadap data itu dapat menghasilkan hasil yang tidak terduga dengan mengembalikan data yang belum dilakukan dalam database.

Apakah penguncian transaksi yang diprakarsai oleh transaksi ini merupakan penguncian yang sama seperti yang dilakukan oleh berbagai basis data melalui konstruksi seperti SELECT FOR UPDATE atau perintah LOCK eksplisit?

Segala sesuatu di server sql terkandung dalam transaksi. Ketika Anda mengakses data Anda, RDBMS harus mengambil kunci tergantung pada tingkat isolasi dan Operasi yang Anda lakukan pada data Anda. Periksa jawaban ini untuk detail lebih lanjut.

Beberapa referensi bagus:

Kin Shah
sumber
2

Saya akan mengatakan transaksi adalah bagian dari "antarmuka" basis data dalam arti bahwa Anda sebagai pengembang memutuskan kapan harus memulai, mengakhiri, apa yang harus dilakukan dalam ruang lingkup transaksi, dll. Kunci, seperti yang saya lihat, milik detail implementasi dan digunakan untuk sinkronisasi akses ke berbagai objek. Dalam kebanyakan kasus, mesin itu sendiri memutuskan apa dan untuk berapa lama harus dikunci. Ada banyak kunci level sistem yang tidak dapat dimanipulasi secara langsung (misalnya, mesin dapat mengunci area memori tertentu). Bahkan ketika datang ke kunci DML, banyak dari mereka terjadi di belakang layar (misalnya, untuk memastikan integritas referensial Oracle dan, sejauh yang saya ingat, SQLServer dapat meletakkan kunci pada baris yang sesuai di tabel master jika catatan baru dimasukkan ke dalam tabel detail) sebagai hasil dari pernyataan DML yang dikeluarkan dalam transaksi.

Ketika berbicara tentang transaksi, Anda dapat mengharapkan perilaku yang kurang lebih konsisten dari RDMS yang mengklaim mematuhi SQL dan mendukung transaksi, tetapi ketika menyangkut penguncian, hampir setiap vendor menggunakan strategi dan terminologi yang berbeda. Bagian umum di semua RMDS sejauh yang saya tahu adalah bahwa konkurensi antara transaksi ditentukan oleh tingkat isolasi sedangkan konkurensi antara kunci dikendalikan oleh jenis kunci (dibagi, eksklusif, dll).

Untuk meringkas, kunci adalah mekanisme tingkat rendah untuk mengontrol konsistensi objek dan konkurensi. Kunci dapat dikeluarkan selama eksekusi pernyataan SQL. Bergantung pada implementasi tingkat isolasi transaksi, mesin dapat menempatkan berbagai jenis kunci pada objek yang terpengaruh (baris, grup baris, indeks, dll). Ada sejumlah perintah yang tersedia untuk mengeluarkan kunci secara manual ( SELECT FOR UPDATE, LOCK). Kunci DML dapat ditingkatkan (tergantung pada RDMS, misalnya, dalam SQLServer baris-> halaman-> partisi-> tabel). Kunci juga dapat dikeluarkan oleh mesin basis data selama inisiasi koneksi, cadangan, pemulihan, prosedur / pemicu / fungsi / dll kompilasi, startup, shutdown, dll.

Saya tidak yakin apakah itu menjawab pertanyaan Anda, tetapi saya harap itu masuk akal.

a1ex07
sumber
Terima kasih atas komentarmu. Anda pasti yang terdekat sejauh ini. Saya masih mencoba untuk melihat apakah transaksi selalu dilaksanakan dalam hal kunci yang digunakan oleh, katakanlah, eksplisit LOCKatau SELECT FOR UPDATEpernyataan, atau melalui beberapa mekanisme lain.
Laird Nelson
Sejauh yang saya tahu, BEGIN TRANSACTIONitu sendiri tidak mengeluarkan kunci. Kunci akan muncul setelah DML dalam transaksi.
a1ex07
Klarifikasi - maksud saya BEGIN TRANSACTIONsendiri tidak membuat kunci DML; sebenarnya harus mengeluarkan beberapa kunci internal karena harus mengalokasikan sumber daya, menambahkan entri ke tabel sistem [s] (jika ada) yang memegang transaksi aktif, dll.
a1ex07
1

Saya akan menggunakan SQL Server jargon, tetapi konsepnya harus sama untuk vendor lain:

Setiap perintah yang Anda jalankan dijalankan di dalam suatu transaksi. Transaksi itu dapat dibuka secara eksplisit dengan BEGIN TRAN, atau secara implisit, oleh mesin basis data. Alasan transaksi implisit dibuka adalah bahwa mesin masih perlu mempertahankan kepatuhan ACID dan kemampuan untuk rollback.

Ketika Anda melakukan SELECT FOR UPDATE, itu hanya berarti bahwa sementara transaksi dilakukan, itu akan menahan kunci tertentu.

Matan Yungman
sumber
Terima kasih atas komentarmu. Setahu saya itu. Tapi pertanyaan saya masih: ketika transaksi itu dibuka, apakah isolasi dilakukan dengan memegang kunci sendiri? Jika demikian, apakah kunci tersebut adalah jenis kunci yang sama yang dapat saya peroleh secara eksplisit? Atau apakah transaksi mencapai isolasi melalui cara lain?
Laird Nelson
2
Ya, ini adalah mekanisme yang sama. Isolasi dicapai dengan menggunakan kunci di kedua mode, kunci yang sama yang Anda dapat secara eksplisit. Perbedaannya adalah bahwa jika Anda tidak secara eksplisit membuka transaksi, kunci akan dilepaskan ketika perintah selesai, sedangkan dalam transaksi eksplisit kunci disimpan sampai Anda melakukan (tidak 100% akurat karena tingkat isolasi, tetapi itulah Ide umum).
Matan Yungman
Terima kasih atas komentarmu. Alasan saya mengajukan pertanyaan saya adalah karena saya membaca di suatu tempat bahwa beberapa database menggunakan MVCC sebagai sarana untuk mencapai transaksi ACID, yang menurut saya merupakan cara bebas kunci untuk melakukannya. Dalam kasus seperti itu, maka, saya tidak jelas kapan saya ingin mengeluarkan kunci secara eksplisit. Tapi itu mungkin pertanyaan terpisah. :-)
Laird Nelson
@ LairdNelson itulah tingkat Isolasi Snapshot untuk SQL Server. Ada, tetapi bukan mekanisme default untuk konkurensi. Ini adalah standar untuk Oracle atau Postgresql, IIRC.
Marian
0

Kunci diperlukan dan mereka membuat basis data. Ini mencegah data dari rusak atau tidak valid ketika beberapa pengguna mencoba membaca sementara yang lain menulis ke database. Isolasi transaksional biasanya dilaksanakan dengan mengunci apa pun yang diakses dalam suatu transaksi. Aplikasi desain yang buruk memanfaatkan konsep kunci basis data :) !! Jadi untuk menghindari kunci berkonsentrasi pada tata letak FK dan data Anda.

Ini semua tentang ACID: - baca ini dan itu akan menjernihkan pikiran Anda! ACID adalah seperangkat properti yang ingin Anda terapkan saat memodifikasi database.

  • ** Atomicity
  • Konsistensi
  • Isolasi
  • Daya tahan**

Transaksi adalah serangkaian perubahan terkait yang digunakan untuk mencapai beberapa properti ACID. Transaksi adalah alat untuk mencapai properti ACID.

Atomicity berarti Anda dapat menjamin bahwa semua transaksi terjadi, atau tidak ada yang terjadi; Anda dapat melakukan operasi kompleks sebagai satu unit tunggal, semua atau tidak sama sekali, dan kerusakan, kegagalan daya, kesalahan, atau apa pun tidak akan memungkinkan Anda berada dalam keadaan di mana hanya beberapa perubahan terkait yang terjadi.

Konsistensi berarti Anda menjamin bahwa data Anda akan konsisten; tidak ada kendala yang Anda miliki pada data terkait yang akan dilanggar.

Isolasi berarti bahwa satu transaksi tidak dapat membaca data dari transaksi lain yang belum selesai. Jika dua transaksi dieksekusi secara bersamaan, masing-masing akan melihat dunia seolah-olah mereka mengeksekusi secara berurutan, dan jika satu perlu membaca data yang ditulis oleh yang lain, itu harus menunggu sampai yang lain selesai.

Daya tahan berarti bahwa setelah transaksi selesai, dijamin bahwa semua perubahan telah direkam ke media yang tahan lama (seperti hard disk), dan fakta bahwa transaksi telah selesai juga dicatat.

Jadi, transaksi adalah mekanisme untuk menjamin properti ini; mereka adalah cara pengelompokan tindakan terkait bersama sehingga secara keseluruhan, kelompok operasi dapat berupa atom, menghasilkan hasil yang konsisten, diisolasi dari operasi lain, dan direkam secara tahan lama.

Up_One
sumber
Terima kasih atas komentar Anda. Saya setidaknya cukup sadar akan sifat-sifat ACID. Yang saya masih belum jelas adalah: apakah transaksi menerapkan ACID dengan menggunakan jenis kunci yang sama yang dapat saya gunakan langsung melalui LOCKpernyataan eksplisit , atau apakah mereka melakukannya menggunakan mekanisme lain?
Laird Nelson
Basis data menawarkan sejumlah tingkat isolasi transaksi, yang mengontrol tingkat penguncian yang terjadi saat memilih data. Dapat dibaca, dibaca berulang, Dibaca berkomitmen, Baca tidak terikat.
Up_One