Apakah tingkat isolasi serializable SQL Server mengunci seluruh tabel

9

Saya dan seorang kolega saya membahas implikasi penggunaan tingkat isolasi serializable. Dia mengatakan itu mengunci seluruh meja, tapi saya tidak setuju dengan mengatakan kepadanya bahwa itu berpotensi tetapi mencoba menerapkan rentang kunci dan itu tidak berlaku serialisasi yang benar dijelaskan di sini: Tingkat Isolasi Serializable .

Saya tidak dapat menemukan apa pun di dokumen untuk "mengunci seluruh tabel": SET TINGKAT ISOLASI TRANSAKSI .

Dokumen menyatakan banyak hal tentang kunci rentang, jadi secara teori Anda bisa mengunci seluruh tabel hanya dengan memiliki kunci rentang yang mengunci seluruh rentang nilai yang mungkin dalam tabel, tetapi itu tidak mengunci tabel.

Apakah saya benar-benar salah di sini? Apakah sebenarnya mengunci seluruh tabel (atau tabel)?

mslot
sumber

Jawaban:

16

Eskalasi, meskipun

Eskalasi kunci di bawah tingkat isolasi serializable dapat terjadi sama seperti halnya dengan tingkat isolasi lainnya.

  • Indeks yang benar dapat membantu menghindari eskalasi kunci hingga titik tertentu
  • Mengunci banyak indeks akan meningkatkan kemungkinan eskalasi kunci; penghitungan bersifat kumulatif di seluruh objek untuk satu pernyataan

Beberapa contoh cepat menggunakan tabel tunggal dengan indeks tunggal. Id adalah kunci utama dan indeks berkerumun di atas meja.

Satu baris

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id = 138; --One value

ROLLBACK

Untuk nilai Id tunggal, penguncian minimal.

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |           1 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |           1 |
+--------------+---------------+---------------+-------------+

Beberapa baris

Tetapi kunci akan naik jika kita mulai bekerja dalam rentang:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 5000; -- Small range

ROLLBACK

Sekarang kami memiliki lebih banyak kunci eksklusif pada lebih banyak kunci:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |        2429 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |          97 |
+--------------+---------------+---------------+-------------+

Lebih Banyak Baris

Ini akan berlanjut sampai kita mencapai titik kritis:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 11655; --Larger range

ROLLBACK

Eskalasi kunci dicoba dan berhasil:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| X            | Comments      | OBJECT        |           1 |
+--------------+---------------+---------------+-------------+

Perhatian

Sangat penting untuk memisahkan dua konsep di sini: tingkat isolasi akan menjadi serial, apa pun kunci yang diambil. Permintaan memilih tingkat isolasi, dan mesin penyimpanan memilih kunci. Serializable tidak akan selalu menghasilkan penguncian jangkauan - mesin penyimpanan dapat memilih jenis pengunci mana saja yang memenuhi tingkat isolasi.

Erik Darling
sumber
5

Jika ada indeks pada predikat pencarian, itu mungkin digunakan untuk kunci rentang .

Yaitu, mengunci dari baris pertama ke berikutnya dalam jangkauan. Dan dari yang di sebelah baris ketiga, dll. Hingga baris terakhir dalam rentang. Jadi pada dasarnya sejumlah kunci baris, tetapi blok rentang dari sisipan juga untuk nilai "di antara" (mengunci rentang).

Agar hal ini terjadi, Anda (SQL Server) perlu memiliki indeks untuk bekerja dengannya. Tanpa indeks untuk melakukan penguncian (indeks pada predikat), Anda (dari apa yang saya tahu) akan mendapatkan kunci tabel.

Tibor Karaszi
sumber