NEDEN YETKİSİZ BİR OKUMA izolasyon seviyesi kullanılmalı?


225

Düz İngilizce'de kullanmanın dezavantajları ve avantajları nelerdir?

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

uygulamaları ve raporlama hizmetleri uygulamaları için bir sorgulama nasıl yapılır?

Yanıtlar:


210

Bu izolasyon seviyesi kirli okumalara izin verir. Bir işlem, başka bir işlem tarafından yapılan taahhüt edilmemiş değişiklikleri görebilir.

En yüksek izolasyon düzeyini korumak için, DBMS genellikle veri kilitleri elde eder, bu da eşzamanlılık kaybına ve yüksek kilitleme yüküne neden olabilir. Bu izolasyon seviyesi bu özelliği rahatlatır.

Birkaç örnek ve daha fazla okuma için Wikipedia makalesineREAD UNCOMMITTED göz atmak isteyebilirsiniz .


Ayrıca Jeff Atwood'un kendisi ve ekibinin Stack Overflow'un ilk günlerinde bir kilitlenme sorunuyla nasıl başa çıktığıyla ilgili blog makalesine göz atmak da ilginizi çekebilir . Jeff'e göre:

Ama nolocktehlikeli mi? read uncommittedİle geçersiz verileri okuyabilir misiniz ? Evet, teoride. Size ve hepsine ASİT bilimini düşürmeye başlayan veritabanı mimarisi astronotlarında herhangi bir sıkıntı görmeyeceksiniz, ancak denemek istediğinizi söylediğinizde bina yangın alarmını çekeceksiniz nolock. Bu doğru: teori korkutucu. Ama bence şu: "Teoride teori ve pratik arasında hiçbir fark yok. Pratikte var."

Asla nolock herhangi bir veritabanı kilitlenme sorunları için yılan yağı düzeltme genel "ne ails için iyi" olarak kullanmanızı tavsiye ederim . Önce sorunun kaynağını teşhis etmeye çalışmalısınız.

Ancak pratikte nolockkesinlikle bildiğiniz sorguları eklemek basit, anlaşılır salt okunur işler asla sorunlara yol açmaz ... Ne yaptığınızı bildiğiniz sürece.

READ UNCOMMITTEDGöz önünde bulundurmak isteyebileceğiniz seviyeye bir alternatif de READ COMMITTED SNAPSHOT. Jeff'ten tekrar alıntı yapılıyor:

Anlık görüntüler tamamen yeni bir veri değişikliği izleme yöntemine dayanır ... sadece küçük bir mantıksal değişiklikten daha fazlası, sunucunun verileri fiziksel olarak farklı şekilde işlemesini gerektirir. Bu yeni veri değişikliği izleme yöntemi etkinleştirildiğinde, her veri değişikliğinin bir kopyasını veya anlık görüntüsünü oluşturur. Çekişme sırasında canlı veriler yerine bu anlık görüntüleri okuyarak, Paylaşılan Kilitler artık okumalarda gerekli değildir ve genel veritabanı performansı artabilir.


13
Yazar, okunmayan / hiçbir kilidin en son kaydedilen veriyi döndürmeyeceğini ima ediyor gibi görünüyor. Anlayışım okunmadan okunuyor, taahhüt edilmemiş işlemlerden bile son ayarlanan değeri döndürecektir. Öyleyse, sonuç "birkaç saniye eski" verilerini almaz. Bu, (veya en azından okuduğunuz verileri yazan işlem geri alınırsa), var olmayan veya hiçbir zaman taahhüt edilmemiş verileri almak olabilir. Yanlış mıyım?
xr280xr

4
Mükemmel cevap. BTW, Oracle, muhtemelen Sql Server onu tanıtmadan onlarca yıl önce bildiğimden beri varsayılan olarak "anlık görüntü" vardır. SQL Server ile başlarken oldukça hayal kırıklığına uğradım ve tüm eşzamanlılık sorunlarının "ilkel" kilitleme mekanizmaları kullanılarak çözüldüğünü öğrendim. Oracle'da "Okunmadı" ifadesini hiç görmedim. Ve uygulayıcı astronotlar kadar mutlu.
Stefan Steinegger

13
READ UNCOMMITTEDayrıca satırları iki kez okumanıza veya tüm satırları kaçırmanıza neden olabilir . Okurken bir sayfa bölme gerçekleşirse, tüm veri yığınlarını kaçırabilirsiniz. WITH(NOLOCK)yalnızca sonuçların doğruluğu önemli değilse kullanılmalıdır
Ian Boyd

8
@DanielNolan, Jeff'in ne yaptığını bilmediği için bu makaleyi tavsiye etmek tehlikelidir . Okuma-onaylanmamış, sadece veri okumak için hiçbir zaman değiştirilmeyecektir. Bunu, yazılacak tabloları okumak için kullanmaya çalışmak , pratikte geri alınan bir şeyi okuyacağınız anlamına gelir . Sadece birkaç saniye eski verileri okuyorsunuz, ama siz .................................. ................... ........................... ....
Pacerier

5
................................... asla taahhüt edilmeyen verileri okuyor . Bozuk okumaların tanımı budur. Ve bu taahhüt edilmeyen okumaların sonuçlarına dayanarak yazacaksanız , pratikte bozuk veriler yazacaksınız. Makalede ayrıca "web uygulamalarında büyüyen MySQL'in SQL Server'dan çok daha az kötümser olduğu" belirtildi. Doğru değil, Sql Server varsayılan olarak okuma-taahhütlü seviyede, MySQL ise varsayılan olarak tekrarlanabilir-okumalarda , okuma-taahhütsüzden beş seviye uzakta çalışır.
Pacerier

36

Bu, uzun kesici uç sorgularının ilerlemesini görmek, kaba tahminler (benzer COUNT(*)veya kaba SUM(*)) yapmak vb. İçin yararlı olabilir.

Diğer bir deyişle, kirli okuma sorgularının döndürdüğü sonuçlar, tahmin olarak değerlendirdiğiniz ve bunlara dayalı herhangi bir kritik karar vermediğiniz sürece iyidir.


36

En sevdiğim kullanım durumu read uncommited, bir işlemin içinde olan bir şeyi ayıklamak.

Kod satırlarında adım adım ilerlerken yazılımınızı bir hata ayıklayıcı altında başlatın, bir işlem açar ve veritabanınızı değiştirir. Kod durduğunda, bir sorgu analizörü açabilir, okunmamış yalıtım düzeyini ayarlayabilir ve neler olup bittiğini görmek için sorgulamalar yapabilirsiniz.

Ayrıca, uzun süren yordamların takılıp takılmadığını veya veritabanınızı doğru şekilde güncelleştirip güncellemediğini görmek için de kullanabilirsiniz.

Şirketinizin aşırı karmaşık saklı prosedürleri yapmayı sevmesi harika.


6
Şirketim aşırı karmaşık saklı yordamlar yapmayı çok seviyor. Sorun giderme için ne harika bir fikir!
Brandon

22

Avantajı, bazı durumlarda daha hızlı olabilmesidir. Dezavantajı, sonuç yanlış olabilir (henüz işlenmemiş veriler iade edilebilir) ve sonucun tekrarlanabilir olduğuna dair bir garanti yoktur.

Doğruluğu önemsiyorsanız, bunu kullanmayın.

MSDN hakkında daha fazla bilgi :

Kirli okuma veya izolasyon seviyesi 0 kilitleme uygular, bu da paylaşılan kilitlerin verilmediği ve özel kilitlerin onurlandırılmadığı anlamına gelir. Bu seçenek ayarlandığında, taahhüt edilmemiş veya kirli verileri okumak mümkündür; verilerdeki değerler değiştirilebilir ve işlem bitmeden önce veri kümesinde satırlar görünebilir veya kaybolabilir. Bu seçenek, bir işlemdeki tüm SELECT ifadelerindeki tüm tablolarda NOLOCK ayarının yapılmasıyla aynı etkiye sahiptir. Bu, dört izolasyon seviyesinin en az kısıtlayıcı olanıdır.


Bu, sorgunun hızını nasıl etkiler?
Kip Real

11
@Kip - selectifadeler, yalnızca diğer işlemler tarafından kilitlenen kaynaklar üzerinde paylaşılan kilitler edinmek için beklemek zorunda kalmayacaktı.
Jarrod Dixon

15

Ne zaman kullanılabilir READ UNCOMMITTED?

Temel kural

İyi : Sürekli değişen toplamları gösteren büyük toplu raporlar.

Riskli : Neredeyse her şey.

İyi haber şu ki, salt okunur raporların çoğu bu İyi kategorisine giriyor .

Daha fazla detay...

Kullanmak için Tamam:

  • Mevcut, statik olmayan veriler için neredeyse tüm kullanıcılara yönelik toplu raporlar, örn. Yılbaşından bugüne satışlar. Giriş hatası veya sadece verilerin dakikadan dakikaya tam olarak ne zaman kaydedildiği gibi rastgele belirsizlik gibi diğer belirsizlik faktörlerinden çok daha düşük bir hata payı (belki <% 0,1) riski altındadır.

Bu muhtemelen bir İş Zekası departmanının SSRS'de yapacağı işlerin çoğunu kapsar. Tabii istisna, önünde $ işaretleri olan bir şeydir. Birçok kişi, müşteriye hizmet vermek ve bu parayı üretmek için gerekli temel metriklere uygulanandan çok daha fazla gayretle para kazanır. (Muhasebecileri suçluyorum).

Riskli olduğunda

  • Ayrıntı düzeyine inen raporlar. Bu ayrıntı gerekirse, genellikle her satırın bir kararla ilgili olacağını ima eder. Aslında, engellemeden küçük bir altkümeyi çekemiyorsanız, şu anda düzenlenmiş olmasının iyi bir nedeni olabilir.

  • Tarihsel veri. Nadiren pratik bir fark yaratır, ancak kullanıcılar sürekli değişen verilerin mükemmel olamayacağını anlasa da, statik verilerle aynı şeyi hissetmezler. Kirli okumalar burada incinmez, ancak çift okumalar bazen olabilir. Zaten statik veri üzerinde blok olmamalı olarak görmek, neden risk alsın?

  • Yazma yeteneğine sahip bir uygulamayı besleyen neredeyse her şey.

Tamam senaryosu bile uygun olmadığında.

  • Büyük tekli işlemleri kullanan herhangi bir uygulama veya güncelleme işlemi var mı? Rapor ettiğiniz birçok kaydı kaldıran ve tekrar ekleyen olanlar? Bu durumda NOLOCK, bu tablolarda hiçbir şey için gerçekten kullanamazsınız .

Raporlar hakkında iyi bir nokta. Aslında aklıma gelen ilk fikir, read uncommittedkullanıcı veri doğruluğunun çok önemli olmadığı bazı kullanıcı arayüzü ızgarası gördüğünde web uygulamaları için kullanmam gerektiğiydi . Kullanıcı sadece hangi kayıtların olabileceğini ve belki de bazı sayfalama, sıralama ve filtreleme ile hızlı bir genel bakış ister. Yalnızca kullanıcı Düzenle düğmesini tıklattığında, daha kesin yalıtım düzeyiyle en güncel kaydı okumaya çalışırım. Böyle bir yaklaşım performans açısından daha iyi olmamalı mı?
JustAMartin

Evet, bence makul. Daha önemli bir sorunun, düzenleme düğmesine basma zamanı ile gönderme zamanı arasında verilerin başka biri tarafından değiştirilmediğinden emin olmak olduğunu unutmayın. Gibi verileri getirerek bir işlem başlatarak bunu halledebilirsiniz select item from things with (UPDLOCK). Hızlı bir zaman aşımı süresi koyun, böylece kilidi hızlı bir şekilde elde edemezse kullanıcıya düzenlendiğini söyler. Bu, sizi yalnızca kullanıcılardan değil, geliştiricilerden de koruyacaktır. Buradaki tek sorun, zaman aşımlarını ve bunu kullanıcı arayüzünde nasıl ele aldığınızı düşünmeye başlamak zorundasınız.
Adamantish

6

Raporlama ile ilgili olarak, bir sorgunun veritabanlarını kapatmasını önlemek için tüm raporlama sorgularımızda kullanırız. Bunu yapabiliriz çünkü mikrosaniye veriyi değil tarihsel verileri çekiyoruz.


4

Kaynağın değişme olasılığının düşük olduğu durumlarda READ_UNCOMMITTED kullanın.

  • Geçmiş verileri okurken. örneğin, iki gün önce gerçekleşen bazı dağıtım günlükleri.
  • Meta verileri tekrar okurken. örn. meta veri tabanlı uygulama.

Getirme işlemi sırasında sosun değişebileceğini bildiğinizde READ_UNCOMMITTED kullanmayın.


1
Tersinin geçerli olduğunu hissediyorum. Öncelikle statik veriler blok olmadan iyi okunmalıdır. O takdirde gelmez ardından engellemek artık düzeltme için önemli bir asma işlemi problem var keşfettim. Ayrıca kullanıcılar, geçen yılın yıllık raporu için yazdırdıkları her şeyle son ondalık basamağa kadar eşleşmelerini bekler. Genellikle sürekli akı içinde olduğunu bildikleri raporların aynısını beklemezler. Bu, ayrıntılı, son derece zaman duyarlı veya finansal raporlama için geçerli değildir, ancak 1000'de 1 giriş hatası tolere edilebilirse, öyle de olur READ UNCOMMITTED.
Adamantish

TLDR: Veriler değişmezse, yine de blok olmadığından OKUYUNUZU OKUYUNUZ gerekmez. Yanılıyorsanız ve bu durum değişiyorsa, kullanıcıların beklenenden daha kirli veriler almasını engellediğiniz iyi bir şeydir.
Adamantish

Evet, burada @Adamantish ile hemfikirim - READ UNCOMMITTEDverilerinizin aktif olarak kullanıldığı ve çoğu kullanıcının dikkatsizce kötüye kullandıkları bazı olası kilitlenmeleri ve işlem geri alımlarını önlemek için sunucudaki yükü azaltmak istediğinizde en iyi şekilde yararlanabilirsiniz. " Yenile "düğmesini tıklayın. Bir grup kaydı aynı anda görüntüleyen kullanıcılar, verilerin biraz modası geçmiş veya kısmen güncellenmiş olması durumunda genellikle çok fazla umursamazlar. Yalnızca bir kullanıcı bir kaydı düzenlemek üzereyken, ona en doğru verileri vermek isteyebilirsiniz.
JustAMartin

2

Bu size kirli okumalar verir ve henüz yapılmayan işlemleri gösterir. En açık cevap bu. Bunu sadece okumalarınızı hızlandırmak için kullanmak iyi bir fikir değil. İyi bir veritabanı tasarımı kullanıyorsanız bunu yapmanın başka yolları vardır.

Neler olmadığını not etmek de ilginç. READ UNCOMMITTED yalnızca diğer tablo kilitlerini yok saymaz. Ayrıca kendi başına herhangi bir kilit oluşturmaz.

Büyük bir rapor oluşturduğunuzu veya büyük ve muhtemelen karmaşık bir SELECT ifadesi kullanarak veritabanınızdan veri taşıdığınızı düşünün. Bu işleminiz sırasında paylaşılan bir tablo kilidine yükseltilebilecek paylaşılan bir kilide neden olur. Diğer işlemler tablodan okunabilir, ancak güncellemeler mümkün değildir. Üretim tamamen durduğundan bu bir üretim veritabanı ise bu kötü bir fikir olabilir.

UNCOMMITTED READ kullanıyorsanız, masada paylaşılan bir kilit ayarlamazsınız. Bazı yeni işlemlerden sonuç alabilirsiniz veya verilerin nereye eklendiğine ve SELECT işleminizin ne kadar süre boyunca okuduğuna bağlı olmayabilir. Örneğin, bir sayfa bölünmesi oluşursa (veriler veri dosyasındaki başka bir konuma kopyalanacaktır) aynı verileri iki kez de alabilirsiniz.

Dolayısıyla, SELECT'inizi yaparken verilerin eklenebilmesi sizin için çok önemliyse, UNCOMMITTED'i OKUYUN mantıklı olabilir. Raporunuzun bazı hatalar içerebileceğini düşünmelisiniz, ancak milyonlarca satıra dayanıyorsa ve sonucu seçerken yalnızca birkaçı güncellenirse, bu "yeterince iyi" olabilir. Bir satırın benzersizliği garanti edilemeyebileceğinden, işleminiz hep birlikte başarısız olabilir.

SNAPSHOT İZOLASYON SEVİYESİNİ kullanmak daha iyi bir yol olabilir, ancak uygulamalarınızın bunu kullanmak için bazı ayarlamalar yapması gerekebilir. Bunun bir örneği, uygulamanızın başkalarının okumasını ve kullanıcı arayüzünde düzenleme moduna girmesini önlemek için bir satırda özel bir kilit almasıdır. SNAPSHOT İZOLASYON SEVİYESİ ayrıca önemli bir performans cezası ile birlikte gelir (özellikle diskte). Ancak sorunun üstesinden donanım atarak bunu aşabilirsiniz. :)

Bir veri ambarına veri raporlamak veya yüklemek için kullanmak üzere veritabanının bir yedeğini geri yüklemeyi de düşünebilirsiniz.


0

Basit bir tablo için, örneğin, mevcut satıra güncelleme yapılmadığı ve diğer tabloya hiçbir fk değerinin bulunmadığı, sadece eklenebilir bir denetim tablosunda kullanılabilir. Ek parça, geri dönüş şansı olmayan veya az olan basit bir ektir.


-7

Şimdi her zaman OKUYU TUTULMADI kullanıyorum. En az sorunla hızlı. Diğer izolasyonları kullanırken neredeyse her zaman bazı Engelleme sorunlarıyla karşılaşırsınız.

Otomatik Artış alanlarını kullandığınız ve kesici uçlara para cezanızdan biraz daha fazla dikkat ettiğiniz sürece ve engelleme sorunlarına elveda diyebilirsiniz.

READ UNCOMMITED ile hata yapabilirsiniz, ancak dürüst olmak gerekirse, insertlerinizin tam kanıtı olduğundan emin olmak çok kolaydır. Bir seçimin sonuçlarını kullanan Ekler / Güncellemeler, dikkat etmeniz gereken tek şeydir. (Burada OKULULAN OKUYUN veya kirli okumaların soruna neden olmadığından emin olun)

Kirli Okumalara (özellikle büyük raporlar için) gidin, yazılımınız daha sorunsuz çalışacaktır ...


6
Bu çok yanlıştır ve sadece nolock ile ortaya çıkabilecek sorunların yüzeyine dokunur. Sayfalar bölünebilir, birleştirmeler başarısız olabilir, var olmayan verileri veya yinelenen verileri okuyabilirsiniz. Kullanımını kusursuz yapmanın bir yolu yoktur: bu izolasyon seviyesi altındaki hiçbir şeyin doğruluğuna güvenemezsiniz.
TAAHHÜT

@MarkSowul Bu cevabın aşağı doğru yönlendirilmesi bana haksızlık ediyor. @Clive, Committedekler ve güncellemeler için geçeceği açıktı . Diğer sorunlara gelince, Otomatik artan bir anahtar kullanmanın söz konusu olduğu sayfalara ayrılmış konular hakkında farkındalık gösterdi. Sadece bir insan tarafından okunmak üzere yapılan neredeyse tüm canlı raporların son ondalık basamaktaki küçük tutarsızlıkları tolere edebileceğini kabul ediyorum. Makinenin okunması ve dönüştürülmesi istenen detaylı listeler veya veriler için farklı bir hikaye olduğunu kabul ediyorum ve Clive de öyle.
Adamantish

1
Bu yorum aynı zamanda nolock ile gelen olası sorunların tam olarak anlaşılamamasını da göstermektedir. "Son ondalık basamaktaki hafif tutarsızlıklar" neredeyse hiç örtmüyor. "Ekler / güncellemeler için sadece okunan okumayı kullan" seçeneğine dokunmak bile genel öneri olarak yanlıştır (ya "yoksa bir kayıt ekle" ise). Her halükarda, "[okunmamış okunan] en az sorunla hızlıdır" kategorik olarak yanlıştır.
Mark Sowul

Kayıt için, cevabınıza katılıyorum, Adamantish: kabaca doğru toplamalar ve çok az şey.
Mark Sowul
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.