Merhaba arkadaşlar, bu yazıda başlıkta da belirtildiği gibi MS SQL server’da NOLOCK, READPAST ve READUNCOMMITED ifadelerinin ne işe yaradığı ve kullanımı hakkında sizlere bilgi vermeye çalışacağım. Bu makaledeki işlemlerin kolaylıkla anlaşılabilmesi için öncesinde başlangıç seviyesinde MS SQL Server bilgisine sahip olunması gerektiğini de hatırlatmak isterim.
Aslında bu makalenin yazılmasına neden olan durum;
“Acaba MS SQL Server’da oluşturulan bir VIEW dan sorgu çekerken içerisinde kilitlenmiş durumda olan tabloların olabileceği durumlarda “NOLOCK” ifadesini kullanmak VIEW’ın içerisinde kullanılmış olan veritabanı tabloları için de geçerli olacak mıdır?” sorusunun ortaya çıkmasıyla oluştu.
Bu sorunun cevabı olarak;
“Evet bir View’ı NOLOCK ifadesi ile çağırdığınızda tüm derinliklerine kadar etki eder. Bu durum READPAST ve READUNCOMMITED ifadeleri için de geçerlidir.” diyebiliriz.
Ben makale konusu olan komutlar hakkında kısaca bilgi verdikten sonra, bahsi geçen konu için daha rahat anlaşılabilmesi maksadıyla uygulamalı olarak denenebilecek şekilde bir örnek de sunuyor olacağım sizlere.
NOLOCK: Kendisi üzerinde değişiklik yapılan tabloda, yapılan değişiklikler henüz tamamlanmamış da olsa(TRANSACTION sonlandırılmamış da olsa). İlgili kayıtlar sanki işlemler tamamlanmış gibi elde edilebilir.
READPAST: Tabloda yapılan değişiklikler göz önünde bulundurulur ancak sadece üzerinde TRANSACTION sürecinde kilit bulunmayan kayıtlar elde edilebilir. Tüm kayıtların elde edilebilmesi için başlatılan TRANSACTION sürecinin sonlandırılmış olması yani sql deyimi ile COMMIT edilmiş olması gerekmektedir.
READUNCOMMITED: NOLOCK ile aynı özelliklere sahiptir
Bir örnek ile konuyu daha anlaşılır hale getirelim;
Not: Aşağıdaki örnek için makalenin ekinde bulunan sql uzantılı dosyaları da kullanabilirsiniz.
Aşağıdaki 2 faklı bölüm olarak belirtilen komutları SQL Server üzerinde 2 farklı Yeni sorgu ekranında(TAB) sırasıyla çalıştırmalısınız.
1.Bölüm:
--1. Tablo
CREATE TABLE TestTable_1
(
ID INTEGER IDENTITY(1, 1) NOT NULL,
ACIKLAMA VARCHAR(100) NULL
)
GO
--2. Tablo
CREATE TABLE TestTable_2
(
ID INTEGER IDENTITY(1, 1) NOT NULL,
ACIKLAMA VARCHAR(100) NULL
)
GO
-- 1. ve 2. Tablonun içerdiği kayıtların tamamının listelendiği View tanımı
CREATE VIEW TestView_1
AS
SELECT * FROM TestTable_1 T1
UNION ALL
SELECT * FROM TestTable_2 T2
GO
-- 1. View ve 2. Tablonun içerdiği kayıtların tamamının listelendiği View tanımı
CREATE VIEW TestView_2
AS
SELECT * FROM TestView_1 V1
UNION ALL
SELECT * FROM TestTable_2 T1
GO
--1. Tabloya test için eklenen kayıtlar
INSERT INTO TestTable_1(ACIKLAMA) VALUES('A1')
INSERT INTO TestTable_1(ACIKLAMA) VALUES('A2')
INSERT INTO TestTable_1(ACIKLAMA) VALUES('A3')
INSERT INTO TestTable_1(ACIKLAMA) VALUES('A4')
GO
--2. Tabloya test için eklenen kayıtlar
INSERT INTO TestTable_2(ACIKLAMA) VALUES('B1')
INSERT INTO TestTable_2(ACIKLAMA) VALUES('B2')
INSERT INTO TestTable_2(ACIKLAMA) VALUES('B3')
GO
--Transaction başlatılır ve 1. Tablo üzerinde yeni kayıt ekleme ve güncelleme işlemlerinin yapılması sayesinde tablonun kilitlenmesi(LOCK) sağlanır.
BEGIN TRAN
INSERT INTO TestTable_1(ACIKLAMA) VALUES('A5')
UPDATE TestTable_1 SET ACIKLAMA = 'A2_2' WHERE ID = 2
Aşağıdaki komentlenmiş satırlar(yorum olarak anlaşılan, SQL tarafından kod parçası olarak hesaba katılmayan) testleriniz sonrasında oluşturulan tablo ve viewları kaldırabilmeniz için gerekli komut satırladırır. ROLLBACK TRAN ifadesi ile, başlattığınız süreci spnlandırabilir ve tablolar üzerinde yaptığınız değişiklikleri geri alabilirsiniz
-- ROLLBACK TRAN
--
-- GO
--
-- DROP VIEW TestView_1
-- DROP VIEW TestView_2
-- DROP TABLE TestTable_1
-- DROP TABLE TestTable_2
2.Bölüm:
SELECT * FROM TestView_1 à Test1 tablosunda lock(kilit) olduğu için sonuç dönmeyecek
SELECT * FROM TestView_1(NOLOCK) à View'ın içerisindeki tablolar için de TRANSACTION ISOLATION LEVEL değerini READ COMMITTED olarak değiştirileceği için sonuç gelecektir. Gelen sonuç INSERT ve UPDATE işlemleri gerçekleştirilmiş gibi hesaplanır.
SELECT * FROM TestView_1(READPAST) à READPAST komutu ile tablodaki görüntülemek istediğinizde üzerinde değişiklik yapılmakta olan ve TRANSACTION işlemi henüz onaylanmamış olan kayıtlar listelenmeyecektir. Dikkat edilirse 1. Tablodaki ID değeri 2 olan kayıt güncellenmeye çalışılmaktadır ve AÇIKLAMA alanı A5 olarak kaydedilmeye çalışılan kayıt üzerinde de henüz onaylanmadığı(COMMIT) için ve kilit(LOCK) bulunduğu için listelenmeyecektir.