Makale, ortakzamanlılıkta(concurrency)
ortaya çıkan dört ana problem ve bu problemler karşısında kullanılabilecek izolasyon
seviyelerini ele almakta, basit bir örnek ile bir izolasyon seviyesi ayarlaması
anlatılmaktadır.
Giriş
Ortakzamanlılık(concurrency),
aynı kaynağı aynı zamanlarda kullanmak durumunda olma için kullanılan bir terimdir.
Örneğin, bir makaleyi ele alacak olursak, teknik editör bu makalenin teknik
ayrıntıların geçerliliği üstünde çalışırken, bir başka editör de yazıda bir
imla hatası kontrolü yapıyor olabilir. Bu durumda, makaleye ortakzamanlı erişim
sözkonusudur. Kaynağa erişecek her istemcinin(editörün) aynı anda aynı işi yapmasa
bile ortak bölgelerde bulunması bu durum için yeterlidir.
Kurumsal seviye
VTYS’lerle çalışırken, transaction olarak ele alınan işlemlerde en önemli noktalardan
biri, ortak zamanlı erişim için geçerli politikaya karar vermektir. Ne zaman
ortak çalışmaya izin verilmeli, ne zaman kaynaklar, diğer erişimlere bir süre
kapatılmalı gibi sorular bu noktada cevaplanması gereken sorulardır. Bu makalede,
ortak zamanlı erişim sorunu ve yaklaşım tarzları ile SQL Server’in sunduğu yöntemler
ele alınacaktır.
Ortak Zamanlı
Erişim Sorunları
Ortak zamanlılığın
basit bir tanımından sonra, ortak zamanlı erişimin doğurabileceği neticeleri
ele alalım. Ortak zamanlarda aynı kaynağa erişim, yeterli önlemler alınmadığında
çeşitli sakıncalar doğurabilir. Bu sakıncalar 4 ana problem olarak standardize
edilmiştir:Kayıp Güncelleme, Tekrarlamasız Okuma, Hayalet Okuma ve Kirli Okuma.
Bu problemlerden her birini ayrıntılı olarak ele alalım:
- Kayıp
Güncelleme(Lost Update): Aynı satıra erişen birden fazla transaction
olduğunda, bu transaction’lardan verisini en son değiştiren, daha önceki güncellemelerin
kaybolmasına neden olur. Örneğin, bir iş anlaşmasını ele elalım. İki yetkili
tarafından açılmış ve düzenlemeler yapılıyor olsun. Yetkililerden biri düzenlemeler
yapıp kaydettiğinde, ikinci yetkili bu düzenlemeleri asla farketmeyecektir
ve ilk kaydetme işleminde birinci yetkilinin yaptığı düzenlemeler kaybolacaktır.
Bu sorunu engellemek için, ortak zamanlılığı, birinci yetkilinin işi bitinceye
kadar kaynağa erişimi kısıtlayacak şekilde düzenlemek(kilitlemek) gerekir.
- Kirli
Okuma(Dirty Read): Bir transaction tarafından değiştirilmiş ama henüz
kalıcı hale getirilmemiş bir bilginin başka bir transaction tarafından gerçek
kayıtmış gibi okunmasıdır. Örneğin, iş anlaşma taslağını ele alacak olursak,
yetkililerden biri üstünde değişiklik yapıp henüz işini bitirmediği halde
değişikliği kaydettiği anda başka biri tarafından sözleşmenin taraflara iletilmesi,
bir kirli okuma problemi doğuracaktır. Bu sorunu engellemek için de yine birinci
yetkilinin bütün işlemleri yapıp sözleşmenin son halini kaydetmesine kadar,
anlaşmaya erişimi ve dağıtılmasını engellemek gerekir.
- Tekrarlamasız
Okuma(Non-Repeatable Read): İkinci bir transaction bir satıra her
erişiminde farklı bir değer okuyor, sadece okuma yapmasına rağmen bir türlü
sabit bir değere ulaşamıyorsa, tekrarlamasız okuma sorunu ortaya çıkar. İş
anlaşma metni örneğine dönecek olursak, yetkililerden biri sözleşmenin son
halini görmek istediğinde bir göz atıp, kapatıyor. Ardından tekrar bakıyor
ve sözleşmenin değiştiğini görüyorsa bu türden bir sorun ortaya çıkacaktır.
Sorunu çözmek için, ortak zamanlılığı şu şekilde düzenlemek gerekir: Sözleşme
taslak halde iken, yani üstünde biri düzeltme yaparken, sözleşmenin son halini
görmek isteyen erişimleri engellemek(kilitleme) gerekir.
- Hayalet
Okuma(Phantom Read): Buraya kadar incelediğimiz sorunlarda hep transaction’lardan
biri okuma yaparken, diğeri güncelleme yapıyordu. Oysa veritabanında her zaman
güncelleme yapılmaz. Bazen silme ve ekleme de yapılır. İşte Transaction’lardan
biri silme veya ekleme(Insert-Update) işlemeri gerçekleşirken diğer bir transaction
bu işlemleri içine alan aralıktaki satırlar üstünde okuma yapıyorsa, ya elde
ettiği satırlardan bir kısmı artık yoktur veya elde ettiği satırlar, bazı
satırları eksik bulunuduruyordur. İş anlaşmasındaki hali ile, sözleşme taslağı
üstünde taraflardan biri değişiklikler yapıp avukatına gönderdiğinde, avukatı
bu değişikliklerin asıl sözleşme ile uyuşmadığını belirtir. Durum ayrıntılı
olarak incelendiğinde, diğer taraftan yeni bir sözleşme metni maddesi eklendiği
veya bir maddenin çıkartıldığı için böyle bir sorunun oluştuğu anlaşılırsa
hayalet okuma sorunu ortaya çıkmış olur. Bu türden durumlara karşı ortak zamanlı
çalışmayı düzenlemek için, orinal sözleşme ikinci tarafa ulaştıktan sonra,
asıl nüshası üstünde ikinci tarafın işi bitinceye kadar, birinci tarafın asıl
kopya üstünde düzenleme yapmamasını sağlamak(kilitleme) gerekir.
Görüldüğü gibi,
ortak zamanlı erişimde meydana gelecek problemlerin çözümünde en temel nokta,
erişimi bir süre için bütün başkalarının veya sadece okuyacakların veya sadece
değiştireceklerin erişimine karşı engellemek gerekmektedir. Bu işleme kilitleme(locking)
denir.
Ortakzamanı Erişim
İzolasyon Seviyeleri
SQL-92 standardı,
ortakzamanlı erişim esnasında kullanılabilecek 4 izolasyon seviyesi öngörür:
İzolasyon
Seviyesi
|
Açıklama
|
Kirli
Okuma
|
Tekarlamasız
Okuma
|
Hayalet
Okuma
|
Read
Uncommitted
|
Bir
transaction okuma yaparken, diğer transaction’lara karşı hiç bir kilitleme
yapmadığından, diğer transaction’lar verileri değiştirebilir. En basit
izolasyon seviyesidir. Veri tutarlılığı uygulamaya bırakılmıştır.
|
+
|
+
|
+
|
Read
Committed
|
SQL
Server’in default yaklaşımıdır. Bir okuma işlemi için erişen transaction
işini bitirmeden, veriler değiştirilebilir.
|
-
|
+
|
+
|
Repeatable
Read
|
Kirli
okuma ve Tekrarlamasız okumalara karşı kilitleme mekanizmasının olduğu
bir izolasyon seviyesidir.
|
-
|
-
|
+
|
Serialisible
|
Veri
eklerken, silinirken veya güncellenirken transaction boyunca veriler erişime
kapatılır. Hiç bir ortak zamanlılık sorunu meydana gelemez ancak işlemler
çok bekler ve deadlock’lar meydana gelebilir.
|
-
|
-
|
-
|
SQL Server ortakzamanlılığı
düzenlemek için bu standartca tanımlanan izolasyon seviyelerine destek sağlar.
Transaction Nasıl
Çalışır
SQL Server, veri
üstünde değişiklik yapacağı zaman, Şayet daha önceden tampon belleğe aktarılmış
bir sayfa değil ise, öncelikle bu verilerin üstünde yer aldığı sayfa(page)ları
disk(HDD)’ten hafızaya(RAM)’da bir bölgeye taşır. Bu bölgeye tampon hafıza(buffer
cashe) adı verilir. Ardından veriler üstünde ilgili değişiklikler yapılır. Üstünde
değişiklik yapılmış ve henüz kalıcı olarak diske kaydedilmemiş sayfalara kirli
sayfa(dirty page) denir.
Kirli bir hafıza
ile ilgili değişim, transaction dosyaları (*.ldf uzantılı dosya)na işaretlenir.
Sayfaların diske aktarılması esnasında doğacak bir soruna karşı önlem olarak
değişiklikler hep bu şekilde öncelikle loglara yansıtılır. Ardından kirli sayfalar
diske aktarılır. Bu işleme de arıtma(flushing) denir.
Transaction İçin
İzolasyonu Belirlemek
Bir transaction
için, SQL Server’in yukarıda belirtilen izolasyon seviyelerinden birinde işlem
yapmasını isteyelim:
Bunun için genel
ifade şu şekildedir:
SET
TRANSACTION ISOLATION LEVEL izolasyon_seviyesi
Bu ifadede, izolasyon_seviyesi
parametresinin yerine, yukarıdaki tabloda verilen parametrelerden biri
gelebilir.
Örnek:
Pubs veritabanında
bulunan kitapların fiyatlarına %0.5’lik bir zam yapacak bir transaction’ımız
olsun. Bu transaction, işini bitirmeden ikinci bir transaction’a kirli okuma(Dirty
Read) yaptırmamız gerektiğini düşünelim. SQL Server’in default ayarları, yukarıda
da ele aldığımız gibi bu türden bir okumaya müsaade etmeyecek şekilde yapılandırılmıştır.
Bu işlem için iki
adet Query Analyzer penceresi açalım ve pencerelerden birincisinde şu kodu çalıştıralım:
USE pubs
GO
BEGIN TRAN
UPDATE titles
SET price = price * 1.05 |
Ardından ikinci
Query Analyzer penceresini açalım ve şu ifadeyi çalıştıralım:
SELECT
titles, price FROM titles |
İkinci sorgunun
uzunca bir süre beklemesine rağmen asla kayıt döndürmediğini göreceksiniz. Bu
nedenle bir süre denedikten sonra sorguyu durdurabilirsiniz.
Burada ikinci oturumun
kirli okuma yapabilmesi için, izolasyon seviyesinin Read Uncommited olarak ayarlanması
gerekir.
Bu durumda ikinci
Query Analyzer penceresinde yazdığımız ifadeyi şu şekilde değiştirelim:
SET TRANSACTION
ISOLATION LEVEL read uncommitted
SELECT titles, price FROM titles |
Ardından ilk pencereye
gidip, zam yapma işleminden vazgeçtiğimizi belirtelim ve işlemi başa saralım:
Bu
ifade ile, transaction da sona erecektir.
DİKKAT:
"Read Commited" olan SQL Server default izolasyon seviyesini, kirli okuma yapacak
olan transaction’da değiştirdiğimize, değişiklik yapan transaction’da bir değişiklik
yapmadığımıza dikkat edin.
Sonuç ve Özet
Sonuç olarak, SQL
Server ortak zamanlılık konusunda standartlar dahilindeki bütün izolasyon seviyelerini
desteklemektedir. Default olarak, "Read Commited" mod’da çalışmaktadır ve bu
modda, kirli okuma yapmak mümkün değildir.
İzolasyon seviyesi,
Transaction başına belirlenebileceği gibi, oturum başına ve tablo başına(sorgu
başına) da belirlenebilir. Ancak bu makale diğer teknikleri ele almamıştır.
Önceden okunmasında
fayda bulunan makaleler
Transaction
Kavramı
Makale:
SQL Server'de Ortak Zamanlılık ve İzolasyon ADO.NET ve SQL Yaşar Gözüdeli
|