Situasi terbaik untuk menggunakan tingkat isolasi BACA TIDAK TERKESAN

10

Seperti yang kita semua tahu, READ UNCOMMITTED adalah tingkat isolasi terendah di mana hal-hal seperti pembacaan kotor dan pembacaan hantu dapat terjadi. Kapan waktu terbaik untuk menggunakan tingkat isolasi ini dan untuk alasan apa mungkin digunakan?

Sebenarnya saya membaca jawaban sebelumnya, tetapi saya tidak dapat memahaminya sepenuhnya karena tidak ada cukup contoh.

Peter Mortensen
sumber

Jawaban:

20

Saya menggunakan READ_UNCOMMITTED(atau NOLOCK) ketika meminta basis data produksi dari SSMS tetapi tidak secara rutin dari kode aplikasi. Praktik ini (bersama dengan petunjuk kueri MAXDOP 1) membantu memastikan pertanyaan biasa untuk analisis data dan pemecahan masalah tidak memengaruhi beban kerja produksi, dengan pemahaman bahwa hasilnya mungkin tidak benar.

Sayangnya, saya melihat READ_UNCOMMITTED/ NOLOCKdigunakan secara luas dalam kode produksi untuk menghindari pemblokiran dengan mengorbankan integritas data. Solusi yang tepat adalah tingkat isolasi versi baris ( SNAPSHOTatau READ_COMMITTEDdengan READ_COMMITTED_SNAPSHOTopsi database ON) dan / atau perhatian pada pencarian dan penyetelan indeks.

Saya baru-baru ini meninjau kode proc di mana satu-satunya perubahan adalah untuk menghapus NOLOCKkarena kadang-kadang mengembalikan hasil yang salah. Menghapus NOLOCKadalah hal yang baik tetapi, mengetahui bahwa baris yang terlewat atau digandakan biasanya terjadi selama pemindaian alokasi tabel besar, saya menyarankan juga refactoring untuk menggunakan UNION ALLteknik untuk mempromosikan penggunaan indeks yang efisien. Permintaan sekarang berjalan dalam beberapa milidetik dengan hasil yang benar, yang terbaik dari semua dunia.

Dan Guzman
sumber
7

Saya pikir itu baik-baik saja dalam beberapa keadaan, selama Anda menerima konsekuensinya, dan tidak punya pilihan lain.

Untuk opsi lain, saya akan mendorong orang untuk menggunakan Read Committed Snapshot Isolasi (RCSI) untuk aplikasi baru, atau SNAPSHOT ISOLATION (SI) untuk aplikasi yang lebih lama, di mana Anda tidak dapat dengan mudah menguji seluruh basis kode untuk kondisi balapan dengan RCSI.

Namun, itu mungkin tidak cocok. Anda mungkin perlu meluangkan waktu ekstra untuk mencintai dan merawat tempdb, dan memastikan tidak ada yang meninggalkan transaksi terbuka yang membuat versi store (dan tempdb) tumbuh dan mengisi disk.

Jika Anda tidak memiliki DBA, atau seseorang yang tugasnya memantau dan mengelola SQL Server Anda, opsi-opsi itu bisa berbahaya. Lebih umum, tidak semua orang memiliki kendali penuh atas kode yang masuk ke server mereka di mana mereka dapat mengubah string koneksi atau kode untuk meminta SI untuk pertanyaan masalah.

Selain itu, kebanyakan orang tidak memiliki masalah penguncian dengan seluruh aplikasi mereka . Mereka memiliki masalah dengan hal-hal seperti melaporkan data OLTP. Jika Anda dapat menerima pertukaran NOLOCK / RU dengan imbalan laporan yang tidak diblokir oleh penulis, lakukan itu.

Pastikan Anda mengerti apa artinya itu. Itu tidak berarti permintaan Anda tidak mengambil kunci apa pun, itu berarti itu tidak menghormati kunci yang diambil oleh permintaan lain.

Dan tentu saja, jika masalah Anda adalah penguncian penulis / penulis, satu-satunya pilihan yang akan membantu adalah SI, tetapi akan membutuhkan banyak pekerjaan pengembang untuk mengimplementasikannya dengan benar dengan penanganan kesalahan, dll.

Erik Darling
sumber
5
Dan jika masalahnya benar-benar hanya melaporkan data OLTP, bongkar itu ke jenis read-only sekunder (AG, pengiriman log, replikasi, atau roll-milik Anda sendiri).
Aaron Bertrand
3
@ AaronBertrand Dan kemudian mereka akan memiliki server kedua untuk dipantau;)
Erik Darling
5

IMHO, satu - satunya kasus penggunaan yang valid untuk READ UNCOMMITTED pada sistem modern adalah ketika men-debug satu sesi dari sesi lain dalam pengembangan, sehingga Anda dapat melihat apa yang dilakukannya saat mis. Proc tersimpan masih berjalan. Biasanya tidak akan pernah digunakan dalam sistem produksi. Mungkin ada beberapa perolehan kinerja kecil tetapi dalam jangka panjang itu tidak akan pernah sepadan.

Gayus
sumber
3

Kami menggunakannya dalam perawatan kesehatan sepanjang waktu.

Sangat jarang untuk baris data individu untuk mengubah mid-query, dan rasio baca / tulis seperti 10.000 / 1 - dan sebagian besar adalah sisipan, bukan pembaruan. Misalnya, ketika antarmuka lab menulis hasil lab pasien ke database, nilai-nilai itu tidak akan pernah berubah.

Ketika data tidak berubah, perubahan satu baris pada suatu waktu. Tidak ada yang memperbarui seluruh kolom (kecuali DBA, ketika mereka mengacaukan sangat buruk).

Di sisi lain, kami menjalankan banyak pertanyaan untuk memindai hal-hal seperti pasien kembali ke UGD dalam 72 jam atau kurang, yang benar-benar memalu tabel.

Dalam 10 tahun SQL perawatan kesehatan, saya belum pernah melihat Rollback Transaction. Saya ingin masuk dan keluar tanpa mengganggu pengalaman pengguna akhir. Jika ada risiko tinggi memperlambat database OLTP dan risiko rendah mendapatkan data yang buruk, saya akan NOLOCK.

Haruskah kita menggunakannya? Mungkin tidak. Secara umum, saya tidak akan mengatakan bahwa banyak dari database aplikasi yang saya kerjakan dirancang dengan baik. Mereka biasanya penuh dengan anti-pola.

James
sumber
4
hanya FYI, dimungkinkan untuk membaca baris yang ditulis sebagian dengan nolock.
Max Vernon
1
Oh! Saya benar-benar perlu meminta atasan saya untuk membeli server lain agar saya dapat mencatatkan barang-barang ini ....
James
3
Anda mungkin tertarik pada postingan blog bagus dari Paul White ini tentang READ UNCOMMITTED, terutama bagian "Membaca Data Yang Rusak": Level Baca yang Tidak Dikomunikasikan
Josh Darnell
1

READ_UNCOMMITTED/NOLOCKadalah pilihan yang baik ketika keakuratan data tidak benar-benar menjadi tujuan utama. Kadang-kadang ketika diperlukan perkiraan jumlah agregat. Sebagai Contoh: Ada prosedur tersimpan yang digunakan untuk tabel INSERT atau UPDATE. Terkadang jumlah catatan yang akan diperbarui atau dimasukkan sangat besar (Ribuan catatan). Selama prosedur tersimpan ini berjalan, kita bisa menjalankan kueri pemilihan sederhana dengan NOLOCKpada tabel target secara berkala untuk melihat apakah itu berkembang dengan lancar (Untuk kueri pembaruan, jika Anda memiliki kolom perubahan status untuk catatan yang diperbarui, kita dapat menggunakan kolom itu untuk menjalankan group bykueri dengan NOLOCKuntuk mengetahui apakah jumlah perubahan status terus berubah).

GirKarr
sumber
0

Ketahuilah bahwa READ UNCOMMITTED memperkenalkan masalah konsistensi tambahan, bukan hanya bacaan kotor. Bergantung pada metode akses, Anda mungkin kehilangan baris, atau bahkan membaca baris yang sama lebih dari sekali. Jika Anda tertarik dengan detailnya, baca artikel Itzik Ben-Gan

SQLRaptor
sumber
3
Baris yang hilang dan baris yang dibaca lebih dari satu kali juga dimungkinkan pada level komitmen baca default. Jika kolom kunci indeks diperbarui selama pemindaian dan bergerak.
Martin Smith
Diskusi sampingan tentang jawaban ini telah dipindahkan ke obrolan .
Paul White 9