Sql Server WITH (NOLOCK)

Bu makalede Sql Server WITH (NOLOCK) konusunu detaylı bir şekilde görmüş olacağız. Herhangi bir sorgu sırasında Sql Server’ın varsayılan davranışını geçersiz kılmak için kullanılan özel bir açık komuttur. WITH (NOLOCK) ifadesi, aynı verileri okuyan veya değiştiren diğer sorguların bitmesini beklemeden satırları okur. Sorgularımızda WITH (NOLOCK) yok ise ilgili sorgu tablomuzun lock’lanmasına sebebiyet verecektir.

WITH (NOLOCK) komutunu kullanırsak transaction bitmemiş olsa dahi select sorgusunun çalıştırıldığı ana kadarki verileri getiririlir, ve arka tarafta transaction devam eder. Ama, bizim select sorgusunu çalıştırdığımız ana kadarki halini bize döndürür. Transaction bitmediği için select çektiğimiz veri değişebilir. Rollback olabilir buda okuduğumuz yeni verinin tekrar eski haline dönmesine sebebiyet verebilir. Her ne kadar avantaj oluştursa da dezevantajlarıda vardır.

Genel olarak, WITH (NOLOCK) genellikle kaçınmanız gereken kötü bir komut olarak kabul edilir. Özellikle NOLOCK ifadesi, veriyi okuduktan sonra geri alınabilecek commit edilmemiş verileri okuyacak, commit edilememiş veriyi okuması sırasında değiştirilen veya silinen verileri okurken meydana gelebilecek Kirli okumaya(dirty reads) yol açabilir, böylece okuduğunuz veriler farklı olabilir veya hiç var olmamış olabilir.

WITH (NOLOCK) ifadesi tekrarlanamayan okumalara da yol açar; bu okuma, aynı verinin birden çok kez okunması gerektiğinde ve bu okumalar sırasında veriler değiştiğinde gerçekleşir. Bu durumda, aynı satırın birden fazla sürümünü okuyacaksınız.

Okuduğumuz verileri henüz okumadığınız yeni bir konuma taşırsak, verileri iki kez okumuş olacağız. Ayrıca, istenen veriler okuma işleminiz sırasında taşınabileceği veya silinebileceği için aşağıdaki hatayla karşılaşabilirsiniz:

Msg 601, Level 12, State 1
Could not continue scan with NOLOCK due to data movement.

WITH (NOLOCK) ifadesi genellikle raporlama sistemleri gibi online olmayan verileri kabul eden sistemlerle çalışırken fayda sağlayabilir. Genellikle verilerin okunduğu tablolarda okunmasına neden olur.

Genellikle kullanım şekli:

SELECT Column_Name
FROM Table_Name WITH(NOLOCK)
WHERE Column_ID = 1;

Örnek vermek gerekirse, bir tablodaki herhangi bir Row güncelleniyor ve select sorgumuz WITH (NOLOCK) ise güncelleme esnasında aynı anda çalışmışsa dönen sonucumuz yeni değerimiz olabildiği gibi transaction Rollback yapıp eski değerimizde olabilmektedir. Yanlış veri ihtimaller dahilindedir.

WITH (NOLOCK) sql server ACID kurallarından biri olan Consistency yani veri tutarlılığın önünede geçmiş olabilir.

Sonuç olarak: Eğer bir tablo (ya da tablo üzerindeki bir satır/sayfa vs.) başka bir işlem tarafından kilitlenmişse (örneğin bir exclusive lock ile), WITH (NOLOCK) bu kilitleri görmezden gelerek o veriyi okumaya çalışır.

Örnek Senaryo:

Transaction A:

BEGIN TRAN
UPDATE Customers SET Balance = Balance - 100 WHERE Id = 1
-- Henüz COMMIT edilmedi

Transaction B:

SELECT * FROM Customers WITH (NOLOCK)
  • Transaction B, Transaction A’nın yaptığı güncellemeyi görebilir.
  • Ama Transaction A ROLLBACK yaparsa, Transaction B geçersiz bir durumu okumuş olur.

Sorgumuzda herhangi bir index yapısına sorgumuzun çalışmasına zorlayabiliriz.

SELECT * FROM Customers WITH (NOLOCK,INDEX(IndexName))

Bu makalede WITH(NOLOCK) ifadesini görmüş olduk. Başka bir makalede görüşmek dileğiyle.

“İşte bu (Kur’ân), bizim indirdiğimiz mübarek bir kitaptır. Buna uyun ve Allah’tan korkun ki size merhamet edilsin.” (En’âm 155)

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir