Dapatkah seseorang menjelaskan implikasi penggunaan with (nolock)
pada permintaan, ketika Anda seharusnya / tidak seharusnya menggunakannya?
Misalnya, jika Anda memiliki aplikasi perbankan dengan tingkat transaksi tinggi dan banyak data dalam tabel tertentu, dalam jenis pertanyaan apa saja nolock boleh? Apakah ada kasus ketika Anda harus selalu menggunakannya / tidak pernah menggunakannya?
sql-server
nolock
Andy White
sumber
sumber
Jawaban:
WITH (NOLOCK) adalah setara dengan menggunakan READ UNCOMMITED sebagai tingkat isolasi transaksi. Jadi, Anda berisiko membaca baris yang tidak berkomitmen yang kemudian dibatalkan, yaitu data yang tidak pernah berhasil masuk ke dalam basis data. Jadi, sementara itu dapat mencegah pembacaan jalan buntu oleh operasi lain, ia datang dengan risiko. Dalam aplikasi perbankan dengan tingkat transaksi tinggi, itu mungkin tidak akan menjadi solusi yang tepat untuk masalah apa pun yang Anda coba selesaikan dengan IMHO.
sumber
NOLOCK
denganSELECT
Anda menjalankan risiko mengembalikan baris yang sama lebih dari sekali (data duplikat) jika data pernah dimasukkan (atau diperbarui) ke dalam tabel saat melakukan pemilihan.Pertanyaannya adalah apa yang lebih buruk:
Untuk database keuangan, kebuntuan jauh lebih buruk daripada nilai yang salah. Saya tahu itu terdengar mundur, tetapi dengarkan saya. Contoh tradisional dari transaksi DB adalah Anda memperbarui dua baris, mengurangkan dari satu dan menambahkan ke yang lain. Itu salah.
Dalam database keuangan Anda menggunakan transaksi bisnis. Itu berarti menambahkan satu baris ke setiap akun. Sangat penting bahwa transaksi ini selesai dan baris-barisnya ditulis dengan sukses.
Mendapatkan saldo akun untuk sementara salah bukanlah masalah besar, untuk itulah rekonsiliasi akhir hari itu. Dan cerukan dari rekening jauh lebih mungkin terjadi karena dua ATM digunakan sekaligus daripada karena pembacaan tidak berkomitmen dari database.
Yang mengatakan, SQL Server 2005 memperbaiki sebagian besar bug yang
NOLOCK
diperlukan. Jadi kecuali Anda menggunakan SQL Server 2000 atau yang lebih lama, Anda seharusnya tidak membutuhkannya.Bacaan Lebih Lanjut
Versi-Tingkat Baris
sumber
Sayangnya ini bukan hanya tentang membaca data yang tidak dikomit. Di latar belakang Anda mungkin berakhir membaca halaman dua kali (dalam kasus split halaman), atau Anda mungkin kehilangan halaman sama sekali. Jadi hasil Anda mungkin sangat miring.
Lihat artikel Itzik Ben-Gan . Berikut ini kutipannya:
sumber
Contoh buku teks untuk penggunaan sah dari petunjuk nolock adalah pengambilan sampel laporan terhadap basis data OLTP yang tinggi.
Untuk mengambil contoh topikal. Jika bank jalanan AS yang besar ingin menjalankan laporan per jam mencari tanda-tanda pertama tingkat kota berjalan di bank, kueri nolock dapat memindai tabel transaksi yang menjumlahkan setoran tunai dan penarikan tunai per kota. Untuk laporan seperti itu, persentase kesalahan kecil yang disebabkan oleh transaksi pembaruan yang dibatalkan tidak akan mengurangi nilai laporan.
sumber
Tidak yakin mengapa Anda tidak membungkus transaksi keuangan dalam transaksi basis data (seperti ketika Anda mentransfer dana dari satu akun ke akun lainnya - Anda tidak melakukan satu sisi transaksi pada suatu waktu - inilah mengapa transaksi eksplisit ada). Bahkan jika kode Anda adalah braindead untuk transaksi bisnis seperti apa adanya, semua database transaksional memiliki potensi untuk melakukan kembalikan secara implisit jika terjadi kesalahan atau kegagalan. Saya pikir diskusi ini jauh di atas kepala Anda.
Jika Anda mengalami masalah penguncian, terapkan versi dan bersihkan kode Anda.
Tidak ada kunci tidak hanya mengembalikan nilai yang salah itu mengembalikan catatan hantu dan duplikat.
Ini adalah kesalahpahaman umum bahwa selalu membuat kueri berjalan lebih cepat. Jika tidak ada kunci tulis di atas meja, itu tidak ada bedanya. Jika ada kunci di atas meja, itu dapat membuat kueri lebih cepat, tetapi ada alasan kunci diciptakan di tempat pertama.
Dalam keadilan, berikut adalah dua skenario khusus di mana petunjuk nolock dapat memberikan utilitas
1) Database server pra-2005 sql yang perlu menjalankan kueri panjang terhadap database OLTP langsung, ini mungkin satu-satunya cara
2) Aplikasi yang ditulis dengan buruk yang mengunci catatan dan mengembalikan kontrol ke UI dan pembaca diblokir tanpa batas waktu. Nolock dapat membantu di sini jika aplikasi tidak dapat diperbaiki (pihak ketiga dll) dan basis datanya baik sebelum 2005 atau versi tidak dapat dinyalakan.
sumber
NOLOCK
setara denganREAD UNCOMMITTED
, namun Microsoft mengatakan Anda tidak boleh menggunakannya untukUPDATE
atauDELETE
pernyataan:http://msdn.microsoft.com/en-us/library/ms187373.aspx
Artikel ini berlaku untuk SQL Server 2005, jadi dukungan untuk
NOLOCK
ada jika Anda menggunakan versi itu. Agar kode Anda terbukti di masa mendatang (dengan asumsi Anda telah memutuskan untuk menggunakan pembacaan kotor) Anda dapat menggunakan ini dalam prosedur tersimpan Anda:SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
sumber
Anda dapat menggunakannya saat Anda hanya membaca data, dan Anda tidak terlalu peduli apakah Anda mungkin mendapatkan kembali data yang belum berkomitmen.
Ini bisa lebih cepat pada operasi baca, tetapi saya tidak bisa mengatakan berapa banyak.
Secara umum, saya sarankan agar tidak menggunakannya - membaca data yang tidak dikomit bisa sedikit membingungkan.
sumber
Kasus lain di mana biasanya tidak apa-apa adalah dalam database pelaporan, di mana data mungkin sudah berumur dan penulisan tidak terjadi. Namun, dalam kasus ini, opsi harus ditetapkan pada tingkat basis data atau tabel oleh administrator dengan mengubah tingkat isolasi standar.
Dalam kasus umum: Anda dapat menggunakannya saat Anda sangat yakin tidak masalah membaca data lama. Yang penting untuk diingat adalah sangat mudah untuk mendapatkan kesalahan itu . Misalnya, meskipun tidak apa-apa saat Anda menulis kueri, apakah Anda yakin ada sesuatu yang tidak akan berubah di basis data di masa depan untuk menjadikan pembaruan ini lebih penting?
Saya juga akan 2nd berpendapat bahwa itu mungkin bukan ide yang baik di aplikasi perbankan. Atau aplikasi inventaris. Atau di mana pun Anda berpikir tentang transaksi.
sumber
Jawaban sederhana - setiap kali SQL Anda tidak mengubah data, dan Anda memiliki kueri yang mungkin mengganggu aktivitas lain (melalui penguncian).
Sebaiknya pertimbangkan permintaan apa pun yang digunakan untuk laporan, terutama jika kueri membutuhkan waktu lebih dari, katakanlah, 1 detik.
Ini sangat berguna jika Anda memiliki laporan tipe OLAP yang Anda jalankan terhadap basis data OLTP.
Namun, pertanyaan pertama yang diajukan adalah "mengapa saya mengkhawatirkan hal ini?" Dalam pengalaman saya, memalsukan perilaku penguncian standar sering terjadi ketika seseorang dalam mode "coba apa saja" dan ini adalah satu kasus di mana konsekuensi yang tidak terduga tidak kecil kemungkinannya. Terlalu sering itu adalah kasus optimasi prematur dan terlalu mudah dibiarkan tertanam dalam aplikasi "berjaga-jaga." Penting untuk memahami mengapa Anda melakukannya, masalah apa yang dipecahkan, dan apakah Anda benar-benar memiliki masalah.
sumber
Jawaban singkat:
Hanya digunakan
WITH (NOLOCK)
dalam pernyataan SELECT pada tabel yang memiliki indeks berkerumun.Jawaban panjang:
WITH (NOLOCK) sering dieksploitasi sebagai cara ajaib untuk mempercepat pembacaan basis data.
Rangkaian hasil dapat berisi baris yang belum dikomit, yang sering kali dibatalkan.
Jika WITH (NOLOCK) diterapkan ke tabel yang memiliki indeks non-clustered maka indeks baris dapat diubah oleh transaksi lain karena data baris sedang dialirkan ke tabel hasil. Ini berarti bahwa set hasil dapat berupa baris yang hilang atau menampilkan baris yang sama beberapa kali.
READ COMMITTED menambahkan masalah tambahan di mana data rusak dalam satu kolom di mana banyak pengguna mengubah sel yang sama secara bersamaan.
sumber
READ UNCOMITTED
tidak akan memengaruhi sama sekali. Ada alasan mengapa itu dimasukkan dalam standar ANSI.2 sen saya - masuk akal untuk digunakan
WITH (NOLOCK
) ketika Anda perlu membuat laporan. Pada titik ini, data tidak akan banyak berubah & Anda tidak ingin mengunci catatan itu.sumber
Jika Anda menangani transaksi keuangan maka Anda tidak akan pernah ingin menggunakannya
nolock
.nolock
paling baik digunakan untuk memilih dari tabel besar yang memiliki banyak pembaruan dan Anda tidak peduli jika catatan yang Anda dapatkan mungkin sudah ketinggalan zaman.Untuk catatan keuangan (dan hampir semua catatan lainnya di sebagian besar aplikasi)
nolock
akan mendatangkan malapetaka karena Anda berpotensi membaca kembali data dari catatan yang sedang ditulis dan tidak mendapatkan data yang benar.sumber
Saya sudah terbiasa mengambil "batch berikutnya" untuk melakukan sesuatu. Dalam hal ini tidak masalah item mana yang tepat, dan saya memiliki banyak pengguna yang menjalankan kueri yang sama ini.
sumber
Gunakan nolock ketika Anda setuju dengan data "kotor". Yang berarti nolock juga dapat membaca data yang sedang dalam proses modifikasi dan / atau data yang tidak dikomit.
Ini umumnya bukan ide yang baik untuk menggunakannya dalam lingkungan transaksi yang tinggi dan itulah sebabnya itu bukan opsi default pada permintaan.
sumber
Saya menggunakan dengan petunjuk (nolock) khususnya dalam database SQLServer 2000 dengan aktivitas tinggi. Saya tidak yakin bahwa itu diperlukan dalam SQL Server 2005. Saya baru-baru ini menambahkan petunjuk itu dalam SQL Server 2000 atas permintaan DBA klien, karena dia memperhatikan banyak kunci catatan SPID.
Yang bisa saya katakan adalah bahwa menggunakan petunjuk TIDAK menyakiti kita dan tampaknya telah membuat masalah penguncian menyelesaikannya sendiri. DBA pada klien tertentu itu pada dasarnya bersikeras bahwa kami menggunakan petunjuk itu.
Omong-omong, basis data yang saya tangani adalah back-end untuk sistem klaim medis perusahaan, jadi kita berbicara tentang jutaan catatan dan 20+ tabel di banyak gabungan. Saya biasanya menambahkan petunjuk WITH (nolock) untuk setiap tabel dalam gabungan (kecuali jika itu adalah tabel turunan, dalam hal ini Anda tidak dapat menggunakan petunjuk tertentu)
sumber
Jawaban paling sederhana adalah pertanyaan sederhana - apakah Anda perlu agar hasilnya berulang? Jika ya maka NOLOCKS tidak sesuai dalam kondisi apa pun
Jika Anda tidak membutuhkan pengulangan maka nolocks mungkin berguna, terutama jika Anda tidak memiliki kendali atas semua proses yang terhubung ke database target.
sumber