Manfaat TINGKAT ISOLASI SET TRANSAKSI BACA TIDAK DIKOMITMASI

12

Saya menggunakan SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDsebagian besar pertanyaan SQL umum saya, terutama karena ini dibor kepada saya ketika awalnya belajar bahasa.

Dari pemahaman saya, level isolasi ini bertindak dengan cara yang sama yang WITH (NO LOCK)bagaimanapun saya cenderung gunakan SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

  • Apakah pernah ada waktu yang saya harus menggunakan WITH (NO LOCK)lebih SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
  • Apakah SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDmenghentikan pengguna lain agar tidak dikunci dari tabel yang saya baca?
  • Jika SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdigunakan untuk menghentikan kunci, tetapi saya hanya membaca data, apa gunanya menggunakannya? Apakah hanya kueri intensif sistem yang akan menghasilkan kunci? Apakah layak menggunakannya ketika menjalankan kueri yang akan kembali dalam mengatakan, 5-10 detik?
  • Saya telah diberitahu untuk tidak menggunakan SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDketika membaca data yang akan digunakan dalam pembaruan, mungkin untuk menghindari memperbarui data kotor. Apakah ini satu-satunya alasan?
  • Dengan jenis database yang saya kerjakan, ada lingkungan produksi dan pengujian. Kami sangat jarang akan menanyakan lingkungan produksi tetapi ketika saya perlu, saya biasanya akan menggunakan SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDdalam permintaan saya. Saya mengerti bahwa pembacaan yang kotor mungkin dilakukan dengan ini. Selain menerima data kembali yang mungkin tidak berkomitmen untuk database (dan karena itu membuang hasil saya) apa jenis 'membaca kotor' apa yang mungkin?

Maaf atas pertanyaan massal.

dmoney
sumber
2
Anda bisa membaca data yang sama dua kali adalah lubang jatuh lain. Menggunakan RU atau NO LOCK sebagai standar adalah ide yang buruk.
James Anderson
9
Saya tidak akan menggunakan di READ UNCOMMITTEDmana-mana, dengan cara yang sama persis seperti saya tidak akan menggunakan di WITH (NOLOCK)mana-mana (mereka pada dasarnya adalah hal yang sama) blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere
Mark Sinkinson
1
Lihatlah ke model isolasi SNAPSHOT. Mereka jauh lebih kuat dari RCU dan juga tidak memblokir atau menyebabkan pemblokiran. Itu terdengar seperti model default yang bagus untuk Anda (bukannya default ke RCU!).
usr

Jawaban:

25

Mengerikan, kau mempelajarinya seperti itu (maaf!).

READ UNCOMMITTEDmari kita baca setiap baris, ya. Bahkan mereka yang saat ini digunakan dalam INSERT, UPDATE, DELETEoperasi. Ini sangat berguna jika Anda perlu melihat beberapa Data atau dalam mission mission SELECT-Statements di mana blok akan sangat berbahaya.

Bahkan, Anda mempertaruhkan integritas Anda. Mungkin Anda membaca satu baris, yang saat ini digunakan untuk dihapus atau dalam perubahan. Dapat juga muncul bahwa Anda membaca nilai yang salah. Ini mungkin benar-benar tidak biasa, tetapi itu bisa terjadi. Apa yang saya maksud dengan itu? Nah, pikirkan sebuah baris yang sangat luas (memiliki banyak kolom dengan banyak kolom panjang nvarchar). Pembaruan terjadi pada baris ini dan menetapkan nilai baru. Dalam kasus yang jarang terjadi, itu bisa terjadi pada Anda, bahwa Anda hanya membaca setengah baris. Hal lain dapat terjadi misalnya, jika pengguna mengubah nilai loginnya. Dia mengubah email + kata sandinya. Email sudah diatur, tetapi kata sandinya tidak. Dengan cara ini Anda memiliki kondisi yang tidak konsisten.

Saya sarankan untuk melupakan READ UNCOMMITTED. Cukup gunakan di tempat yang benar - benar dibutuhkan.

Alternatif lain untuk Anda adalah mengaktifkan READ_COMMITTED_SNAPSHOTopsi database - karenanya Anda dapat menggunakan READ COMMITTED SNAPSHOTkarena versi baris yang diaktifkan di tempdb Anda. Dengan cara ini Anda baru saja membaca versi baris lain (yang lebih lama). Ini tidak akan memblokir Kueri Anda. Tetapi mungkin terjadi bahwa Anda membaca nilai lama juga, tetapi nilai lama yang konsisten.

Gagasan lain bisa jadi WITH(READPAST)bukan WITH(NOLOCK). Anda akan membaca status lama tabel (sedikit seperti pada SNAPSHOT ISOLATION), tetapi Anda akan melewatkan semua baris yang saat ini terkunci.

Ionik
sumber
@Ionic, terima kasih banyak atas jawabannya! Saya sangat menghargai bantuannya.
dmoney
@HingSight, kedengarannya seperti itu, tetapi ada peluang yang sangat bagus bahwa itu adalah interpretasi saya atas pernyataan tersebut, terima kasih atas masukan Anda.
dmoney
1
SNAPSHOT ISOLATIONtidak perlu diaktifkan untuk menghidupkan READ COMMITTED SNAPSHOT. Hanya READ COMMITTED SNAPSHOTopsi basis data yang perlu diaktifkan agar versi baris daripada mengunci konsistensi baca, menghindari kebutuhan untuk membaca kotor.
Dan Guzman
Ya saya maksudkan bahwa @DanGuzman. Maaf jawabannya agak tidak jelas pada saat itu. Saya mengeditnya. :-)
Ionic
Dengan READPAST Anda akan melewati catatan yang dikunci, Anda tidak akan mendapatkan nilai-nilai lama - jadi satu-satunya tempat yang saya pikir dapat digunakan adalah penanganan antrian
James Z
2

Seperti yang dinyatakan dalam jawaban yang diterima, lupakan menggunakan BACA tingkat isolasi BACA (kecuali ketika benar-benar diperlukan) karena Anda berisiko membaca data yang salah. Tetapi untuk menjawab poin ketiga dalam pertanyaan Anda, ada dua situasi yang menurut saya berguna:

  1. Saat menulis dan menguji paket SQL Server SSIS, langkah-langkah paket dapat dibungkus dalam transaksi. Jika Anda menguji suatu paket dengan menjalankannya langkah demi langkah dalam debugger SSIS, Anda mungkin ingin memeriksa tabel sementara ada kunci di atas meja. Menggunakan SET TRANSAKSI ISOLASI TINGKAT BACA TIDAK DIKOMPUTASI memungkinkan Anda menggunakan SQL Server Manager Studio untuk memeriksa tabel saat paket sedang di-debug.

  2. Dalam SQL Server Manager Studio Anda mungkin ingin menguji kode T-SQL dengan membungkusnya dalam transaksi untuk memberi Anda pilihan untuk mengembalikan perubahan. Misalnya pada database pengujian Anda mungkin ingin mengembalikan data ke kondisi awal sebagai bagian dari pengujian Anda. Jika Anda menguji kode yang dibungkus transaksi dan Anda ingin memeriksa tabel yang dikunci saat transaksi sedang berlangsung, Anda dapat menggunakan SET TINGKAT ISOLASI TRANSAKSI BACA YANG TIDAK DICATAT untuk memeriksa nilai-nilai di jendela lain.

Saya menerima bahwa ini adalah penggunaan yang tidak jelas untuk READ UNCOMMITTED, tetapi saya merasa ini berguna dalam lingkungan pengujian.

Ubercoder
sumber
1

Di sebagian besar database, sebagian besar aktivitas, bahkan menyisipkan, menghapus, dan memperbarui, berada di luar transaksi eksplisit.

Tentu, READ UNCOMMITTED(Kotor Dibaca) dapat memberikan informasi yang salah dalam kasus ini, tetapi informasi itu benar 5 detik sebelumnya.

Waktu ketika Baca Kotor menghasilkan hasil yang benar-benar buruk adalah ketika Transaksi gagal dan harus dibatalkan atau ketika menjalankan kueri terhadap dua tabel yang biasanya diperbarui bersama-sama menggunakan transaksi eksplisit.

Sementara itu, pada basis data besar dan sibuk yang memiliki rasio 100 (atau lebih) dari 1 baca untuk ditulis, SETIAP kueri (baca) tunggal yang tidak menggunakan Dirty Reads memperlambat sistem karena perlu untuk mendapatkan dan memeriksa untuk kunci DAN itu membuatnya lebih mungkin bahwa transaksi akan gagal (biasanya karena Deadlock) yang dapat menyebabkan masalah integritas database yang lebih serius.

Sebaliknya, menggunakan pembacaan yang kotor membuat sistem JAUH lebih cepat dan lebih dapat diandalkan (sebagian karena peningkatan kinerja membuat inkonsistensi lebih kecil kemungkinannya terjadi).

Tentu, ada saatnya mereka tidak boleh digunakan. Saya tidak suka pengaturan database ke default untuk menggunakan READ UNCOMMITTEDtingkat isolasi atau bahkan menggunakan SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDpernyataan eksplisit pada awal Script SQL dan SP - ada terlalu banyak kemungkinan bahwa Baca Kotor akan terjadi ketika seharusnya tidak. Alih-alih, (NOLOCK)petunjuknya adalah pendekatan yang jauh lebih baik karena mereka secara eksplisit menunjukkan bahwa programmer memikirkan apa yang mereka lakukan dan memutuskan bahwa, untuk tabel khusus ini dalam permintaan spesifik ini, Dirty Reads aman.

Jika Anda memprogram aplikasi untuk mentransfer uang dari satu rekening bank ke rekening bank lain, Anda tidak boleh menggunakan Dirty Reads. Tetapi sebagian besar aplikasi tidak membutuhkan tingkat paranoia.

Simon Holzman
sumber