MSSQL Server SERIALIZABLE Isolation Level

SERIALIZABLE, MSSQL Server’daki en katı ve en yüksek izolasyon seviyesidir. Bir işlem (transaction) bu seviyede çalıştığında, sanki veritabanında o an sadece o işlem varmış gibi davranır.

Bu seviye, REPEATABLE READ seviyesinin bir adım ötesine geçerek Phantom Reads (Hayalet Okumalar) sorununu da tamamen ortadan kaldırır.

SERIALIZABLE seviyesi, sadece okuduğunuz satırları kilitlemekle kalmaz, aynı zamanda sorgunuzun kriterlerine uyan aralıkları (range) da kilitler. Buna Key-Range Locking denir.

  •  Okuma Kilidi: Sorgulanan tüm satırlar üzerine “Paylaşımlı (S) Kilit” konur.
  •  Aralık Kilidi: Sorgu sonucuna girebilecek potansiyel boşluklar da kilitlenir. Böylece başka bir işlem araya yeni bir kayıt ekleyemez (INSERT).

Oturum bazlı aktif etmek için:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Örnek Senaryo: Hayalet Okumayı Durdurmak

  • Bir banka uygulamasında “Bakiyesi 1000 TL ile 2000 TL arasında olan kaç hesap var?” diye bir rapor aldığınızı düşünelim:
  • İşlem A (SERIALIZABLE): SELECT COUNT() FROM Hesaplar WHERE Bakiye BETWEEN 1000 AND 2000 sorgusunu çalıştırır. Sonuç: 5.
  • Aralık Kilidi: SQL Server sadece mevcut 5 satırı değil, bakiyesi 1000-2000 arasına düşebilecek tüm “boşlukları” kilitler.
  •  İşlem B: Bakiyesi 1500 TL olan yeni bir hesap eklemeye çalışır.
  •  Sonuç: İşlem B bloklanır ve bekletilir. Çünkü İşlem A o aralığı tamamen kapatmıştır.

 İşlem A aynı sorguyu tekrar çalıştırdığında yine 5 sonucunu alır. Tutarlılık %100 sağlanır.

Ö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 SERIALIZABLE Isolation Level seviyesini inceleyelim:


Transaction 1: Müşteri listesini alalım

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION
SELECT * FROM Musteriler;
-- 5 saniye bekleyelim
WAITFOR DELAY '00:00:05';
COMMIT;

Transaction 2: Yeni müşteri eklemeye çalışalım

insert into Musteriler(Ad,Bakiye)values('Veli',15000)

Not: Transaction 1 devam ederken farklı bir transaction’dan select çektiğimizde sonucumuz dönmektedir. Transaction 1 bitene kadar önceki değerler dönmektedir.

Sonuç
İki işlemi farklı sessionlarda çalıştırdığımda Transaction 2, Transaction 1 bitene kadar beklemek zorunda kalır. 
Transaction 1 işlemin sonucunda tablomuzun insert şeklinde gelmediğini görmüş olduk.

Tekrar select çekersek güncel değerin geldiğini görmüş oluyoruz.

Bu isolation levelde Dirty Read, Non-Repeatable Read ve Phantom Read yoktur.

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

dbcc useroptions

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

“Kullarım sana Beni sorarlarsa, bilsinler ki Ben, şüphesiz onlara yakınım. Benden isteyenin, dua ettiğinde duasını kabul ederim. Artık onlar da davetimi kabul edip Bana inansınlar ki doğru yolda yürüyenlerden olsunlar.”Bakara Suresi; 186. Ayet

Author: Yunus YÜCEL

Bir yanıt yazın

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