MSSQL Server SNAPSHOT Isolation Level

Verileri anlık kopyalar ile okur, bu sayede diğer işlemler beklemez. İlk olarak veritabanı seviyesinde bu özelliğin aktif edilmesi gerekmektedir. Okuma tutarlılığı (read consistency) sağlamayı amaçlar. SI,  MVCC (Multi-Version Concurrency Control)mekanizmasını kullanarak, her işlem için verilerin bir “anlık görüntüsünü” (snapshot) oluşturur ve işlemlerin bu görüntüye göre çalışmasını sağlar. Database snapshot işleminin benzeri olarak karşımıza çıkmaktadır.

Snapshot Isolation’ın Temel İlkeleri

1. Anlık Görüntü (Snapshot) Mantığı
Bir transaction başladığında, veritabanındaki verilerin o anki haliyle bir anlık görüntüsü (snapshot) alınır. İşlem boyunca tüm SELECT işlemleri, bu görüntü üzerinden gerçekleştirilir.

2. Okuma (Read) Tutarlılığı
Okuma işlemleri, işlem başladığında alınan snapshot’taki verilere dayanır. Bu sayede, diğer işlemler tarafından yapılan güncellemeler işlem tamamlanana kadar görülmez.

3. Yazma (Write) Çatışmaları
Eğer bir işlem, belirli bir satırı değiştirmek isterse, bu satır başka bir işlem tarafından değiştirilmiş olabilir. SI altında, ilk yazan kazanır (first-writer-wins) prensibi geçerlidir. Yani, eğer bir işlem başka bir işlem tarafından güncellenmiş bir satırı değiştirmeye çalışırsa, hata (write conflict) alır ve işlemi geri alır (rollback).

ALTER DATABASE AdventureWorks2014 SET ALLOW_SNAPSHOT_ISOLATION ON;

Öncelikle, örnek verilerle bir tablo oluşturalım: 

CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY IDENTITY(1,1),
    Ad VARCHAR(50),
    Bakiye DECIMAL(10,2)
);

INSERT INTO Musteriler (Ad, Bakiye) VALUES 
('Ahmet', 1000), 
('Mehmet', 2000), 
('Yunus', 3000);

Şimdi örnekler üzerinden SNAPSHOT Isolation Level seviyesini inceleyelim:

Transaction 1: Müşteri listesini okuyalım. Tablomuzu okuduktan sonra 10 saniye bekleyip diğer işlemlerimizi gerçekleştirip sonuçları gözlemleyelim.

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION
SELECT * FROM Musteriler;
WAITFOR DELAY '00:00:10';
SELECT * FROM Musteriler;
COMMIT;

Transaction 2: Ahmet’in bakiyesini güncelliyoruz. Güncelleme sonucunda Transaction 1 işlemi devam ederken işlemin gerçekleştiğini görüyoruz.

UPDATE Musteriler SET Bakiye = 1 WHERE MusteriID = 1;

Tablomuza select çektiğimizde güncelleme işlemimiz görünüyor. Transaction 1 devam etmektedir.

Transaction 1 işlemimiz devam ederken tablomuza insert işlemi gerçekleştirelim. Transaction 1 devam etmesine rağmen insert işlemi gerçekleşti.( Transaction 3)

insert into Musteriler(Ad,Bakiye)values('OKKES',1000)

Transaction 1 işlemimiz devam ederken tablomuza select çekelim:

Sonuç: 
Transaction 1, Transaction 2 ve Transaction 3’ün yaptığı değişiklikleri görmez. Kendi başlattığı anda var olan verinin bir kopyasını okur.  Transaction 1 işlemi bitmeden önce tablomuza select çektiğimizde insert ve update  değerlerinin döndüğünü görmüş oluyoruz.

Transaction 1 işlemi  sonuç döndüğünde yapılan değişiklikleri görmez.

Örnek olması açısında Transaction 1 işlemini tekrardan başlatıyorum. Bu süre zarfın MusteriID değeri 10 olan veriyi silip dönen sonuçları gözlemleyelim.

Transaction 1 işleminin devam ettiği sırada veri silme işlemi yapılır.

delete from  Musteriler where MusteriID=10

Transaction 1 işlemi sonuçlandıktan sonra snapshot üzerinden verilerin okunduğunu görmekteyiz.

Sql server üzerinde sys.databases komutu çalıştırdığınız snapshot_isolation_state durumu görünür. Bu ifade veritabanı seviyesinde ne kadar aktif edilsede sorgumuzun bu isolation seviyesinde başlatılması gerekmektedir. Yoksa bu değerin 1 veya sıfır olması hiç bir anlam ifade etmez. Bizden with(nolock) aynı yapıya denk gelir bu özelliği böyle kullanmamız daha mantıklı derlerse şöyle bir durum ortaya çıkar. Nolock dirty page’leri yani commit edilmemiş verileri okuma ihtimali var. Genellikle commit edilme ihtimali yüksek commit işlemi saniye dakika bazında gerçekleşir ama snapshot da ise sizin select sorgunuz 30 dakika sürebilir. Tablomuzda binlerce verinin değişmesi silinmesi ihtimali daha yüksektir. Bu da tutarsızlığı çok olan veriler üzerinde işlem yapmanız demek.
Örnek:
– Bir hastanede iki doktor var, her biri en az bir nöbette olmak zorunda.
– İlk işlem: Dr. A nöbetten çekilir, ama Dr. B hala nöbette olduğu için sorun yok.
– İkinci işlem: Dr. B de nöbetten çekilir, ama Dr. A’nın hala nöbette olduğunu düşünüyor.
– Sonuç: İki işlem de başarılı olur ama hastanede nöbette doktor kalmaz!
Anlık görüntüsüne bakarak sonuç dönderir. verinin eklendiği silindiğiyle ilgilenmez.

Aşağıdaki komutla default olan isolation level öğrenilir.

dbcc useroptions

Başka makalede görüşmek dileğiyle..

“Mutlu olanlar ise cennettedirler.” (Hud, 11/108)

Author: Yunus YÜCEL

Bir yanıt yazın

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