HAFTA 7 Transaction Izolasyon- Trigger Kavramları" Yaşar GÖZÜDELİ ygozudeli@verivizyon.com http://blog.verivizyon.com/ygozudeli «BM364» Veritabanı Uygulamaları
Konu Akışı Transaction Kavramı İzolasyon Seviyeleri ve Concurrency Triggerlar 2
Transaction Simitçi ile bozuk para hikayesi... 3
Neden Transaction Ortak zamanlı çalışmada verilerin değiştirilmesinde tutarlılık gerekir Veri Değiştirmede ACID Kuralı Bölünemezlik (Atomicity) Transaction bloğu yarım kalamaz. Ya hep ya hiç Tutarlılık (Consistency) Transaction veritabanının yapısını bozmadan terketmelidir(constraint-trigger vs ile sağlanan iş kuralları) İzolasyon (Isolation) Farklı transaction'lar birbirinden ayrık ele alınmalıdır. Her transaction için veritabanının yapısı ayrı korunmalıdır. Bir transaction bitmeden diğer transaction lar yaptıkları değişikliklerinden haberdar olmamalıdır, bitince hepsinden aynı anda olmalıdır. Dayanıklılık (Durability) Tamamlanmış Transaction'ın hatalara karşı esnek olması gerekir. Elektrik kesilmesi, CPU yanması, O.S. Göçmesi bu kuralları uygulamaya engel olmamalı
Yazılımcı Açısından Transaction faturakod Ürün Bilgileri Fatura Bilgileri
SQL Server açısından Transaction 6
SQL Server'de Transaction Türleri Transaction Başlatma Bitme Harici(Expicit) BEGIN TRAN ile Kullanıcı tarafından COMMIT TRAN, ROLLBACK denilerek kullanıcı veya başka bir sorun olması halinde SQL Server tarafından Dahili (Implicit) Otomatik sabitleme (Autocommit) CREATE, INSERT, UPDATE DELETE gibi bazı ifadeler çalıştıktan sonra SQL Server tarafından otomatik Her bir batch'ten önce SQL Server tarafından otomatik COMMIT TRAN, ROLLBACK denilerek kullanıcı veya başka bir sorun olması halinde SQL Server tarafından Her bir batch'den sonra veya Batch içerisinde bir hata oluşması halinde SQL Server tarafından otomatik
SQL Server'de Transaction Modları Dahili (Implicit) Transaction SET IMPLICIT_TRANSACTIONS ON İle mod aktif hale getirilir. Transaction, şu ifadelerden sonra başlatılır: ALTER TABLE, CREATE, DELETE, DROP, FETCH, GRANT, INSERT, OPEN, REVOKE, SELECT, TRUNCATE TABLE ve UPDATE. Bu ifadelerden biri geçtiğinde, kullanıcının rollback veya commit yapması gerekir. IMPLICIT_TRANSACTIONS OFF ile kapatılır Autocommit SQL Server, IMPLICIT veya EXPLICIT mod'da çalışmıyorsa, autocommit'de çalışır Her bir ifadeden önce bir transaction başlatır. İfadede hata oluştu ise, o ifadenin tamamını kendisi geri alır, olmadı ise sabitler. Harici(Explicit) Transaction Herhangi bir dize ifade ACID'den birine gereksinim duyduğunda programcı başlatır.
Harici Transaction Yönetimi BEGIN TRAN <transaction_ismi> İfadeler COMMIT ROLLBACK Örnek: Bir banka havalesi yapabilecek bir SP yazılmasın 1. Havale yapanın hesabından havale miktarını düşecek 2. Havala yapılanın hesabına havale miktarını ekleyecek 3. Aralarda hata oluştu ise geri alacak (TRY-CATCH veya IF @@ERROR) 4. Oluşmadı ise sabitleyip çıkacak CREATE TABLE tblhesap( HesapNo CHAR(10) PRIMARY KEY NOT NULL, isim VARCHAR(55), soyad VARCHAR(55), sube INTEGER, bakiye MONEY ) INSERT tblhesap VALUES('000000023','Ali','Eryatan',749,30000000) INSERT tblhesap VALUES('000000042','Ahmet','Eryatan',749,30000000)
Konu Akışı Transaction Kavramı İzolasyon Seviyeleri ve Concurrency Triggerlar 10
Ders:Ortak Zamanlılık Denetimi Amaç: Verilerde bozulmaları önlemek ve tutarlılığı korumak Aynı anda iki transaction alamazsak: Seri Transaction Ortak zamanlılık yok Aynı anda iki transaction varsa Bazı problemler ortaya çıkabilir 4 temel problem İyi bir planlama(scheduling) gerekir İki farklı transaction aynı bilgiye erişecekse, aralarından birinde Write varken, çakışma olacaktır. T1 r(a) w(a) r(b) W(B) T1 read(a) write(a) read(b) write(b) commit T2 r(a) A B C T1 r(a) W(A) R(B) T2 r(a) w(a) T2 read(a) write(a) read(c) write(c) commit T1 r(a) W(A) T2 r(a) w(a) w(a) r(c) R(B) r(c) w(c) W(B) w(c) W(B) r(c) w(c)
Ortak Zamanlılık Problemleri DIRTY READ İki transaction'dan birinin değiştirdiği COMMIT edilmeden okunursa bu problem olur. Transaction ROLLBACK olursa??? Aslında okunan veri gerçek olmayabilir. NONREPEATABLE READ Bir transaction ilk açıldıktan sonra okuduğu veri grubu tekrar okuyamaz. Çünkü bu verilerden bir kısmı aynı anda erişebilen başka bir transaction tarafından değiştiriliyordur. Önlemek için başkalarının update etmesini engellemek gerekir FANTOM READ Bir transaction ilk okuyabildiği verileri daha sonra tekrardan okuyabiliyordur ama bunların dışında yeni verilerin eklenmesine engel olamıyordur. LOST UPDATE Açık iki transaction'dan birincisinin değiştirdiği verileri kaydetmesinden sonra ikincisi de üstünde kaydederse, ilkinin yaptığı güncelleme kaybedilir.(snapshot-timestamp)
SQL Transaction İzolasyon Seviyeleri ANSI-92'de belirtilmiştir. Serialisible Mod: En Sıkı mod Hiçbir anomali(ortak zaman erişim sorunu) riski yok Bazen daha az izolasyon gerekebilir. Read Uncommited Read Commited (Default) Repeatable Read İzolasyon yapmadan da Zaman damgası gibi metodlarla ortak zamanlılık sorunları aşılabilir Özellikle lost-update için timestamp türü bir sütun çok kullanışlıdır. Optimistik Yaklaşım, kaynakların çakışmayacağını, çakışmaların programcı tarafından engelleneceğini varsayar SQL Server 2005 de Izolated Transaction desteği
İzolasyon-Problemler İzolasyon Seviyesi Açıklama DIRTY READ NONREPEAT ABLEREAD PHANTOM READ Read Uncommitted Read Committed Repeatable Read Serializable Herkes Herşeyi Yapabilir + + + Sadece commit edilmiş verileri okuyabilir. Ama yeni veri girilmesine ve erişilen verinin değişimine kilit koymaz Birinci transaction okuduğu bölgeleri değişikliğe karşı kilitler Ama yeni kayıt eklenmesine engel olmaz Ortak kaynağa aynı zamanda sadece bir transaction erişebilir - + + - - + - - -
Read Uncommited İzolasyon Seviyesi 0'dır. En kötü izolasyon! Transaction açıkken başka transaction da açık olarak veri değiştirebilir Bütün Fenomenler görünür SELECT ifadesindeki bütün tablolarda NOLOCK varsa = READUNCOMMITED T1 UPDATE tblhesap SET bakiye=bakiye 1000 WHERE hesapno='43' T2 SELECT AVG(bakiye) FROM tblhesap ROLLBACK
Read Commited T1 Veri okunurken, kirli okumayı önler Ama Transaction bitmeden veri değiştirilebilir. Default Seçenek budur. Non-repeatable Read veya Phantom Read olabilir T2 SELECT AVG(bakiye) FROM tblhesap UPDATE tblhesap SET bakiye=bakiye 1000 WHERE hesapno='43' COMMIT SELECT AVG(bakiye) FROM tblhesap COMMIT
Repeatable Read Transaction içerisindeki sorguda geçen bütün veriler kilitlemeye alınır Default'dan daha az bir ortak zamanlılığa müsaade eder. Dirty Read sorununa çözüm Kirli hafızanın okunmasına müsaade etmez NonRepeatable Read sorununa çözüm Değiştiren varsa, okumaya kilitler fantom read sorununa çözüm sağlayamaz. Sonradan eklenen veriler, etki alanı dışındadır. Bir select ifadesindeki bütün tablo adlarından sonra HOLDLOCK geliyorsa=serializable T1 T2 SELECT AVG(bakiye) FROM tblhesap INSERT tblhesap VALUES('33', 'Ali', 'Eryatan', 749, 300) COMMIT SELECT AVG(bakiye) FROM tblhesap COMMIT
Transaction için Seviye Tayini Yapmak SET TRANSACTION <ISOLATION LEVEL UNCOMMITED> BEGIN TRAN <isim>. İşlemler COMMIT ROLLBACK
Örnek Soru İki tane Q.A pencersi açınız. Birinci pencerede: İkinci Pencere: SELECT urunad,listefiyat FROM tblurun Sonuç Geldi mi? SELECT urunad,listefiyat FROM tblurun Başka Nasıl Yapılabilir? USE dukkan GO BEGIN TRAN UPDATE tblurun SET listefiyat = listefiyat * 1.05 SELECT urunad,listefiyat FROM tblurun WITH (NOLOCK)
Kilitlenmeleri Yönetmek sp_who sp_lock ile hangi kullanıcının beklemede kaldığını hangi kullanıcının kilitlenmeye neden olduğunu görebiliriz Hangi kaynaklar kilitli Hangi kullanıcılar kilitliyor SELECT * FROM syslockinfo Management Studio Management Studio / Management/ActivityMonitor kullanarak, kilitlenen process'leri kill edebiliriz. Process Info Hangi process'ler var ve ne aşamada Locks\Process ID Kilitlemede bulunan process'lerin kilitlemelere dağılımı Locks\Object Kilitlenen objelerin gözlemlenmesi
Kilitlenme Çıkmazı İki farklı transaction İki farklı kaynağı kilitlemiş durumda Her birinin bir sonraki adımı diğerinin kilitlediği kaynak Bu nedenle her iki transaction da sonlanamaz Oturum için, zamanaşımı parametresi ayarlamak, sistem kaynaklarının uzun süre kilitlenmesini önler SET LOCK_TIMEOUT milisaniye_sure Bu durumda, bir süre sonra transaction'lardan biri rastsal olarak kurban edilir, diğeri gerçekleştirilir Deadlock'un hata kodu 1205 dir. @@ERROR=1205 ise diye bakılabilir SET DEADLOCK_PRIORITY LOW NORMAL @deadlock_var şeklinde, transaction'lardan istenen birinin kurban seçilmesi sağlanabilir.
Kilitlenmeleri Önlemek Dead-Lock'ları önlemek için 1. Kilitlenen kaynaklara (Nesnelere) aynı sırada erişmek 2. Transaction açtıktan sonra kullanıcıdan bilgi girmesi gibi uzun soluklu işlemlere yer verilmemeli 3. Transaction mümkün olduğu kadar kısa ve tek batch halinde tutulmalıdır. 4. Düşük seviyeli oturum izolasyon seçenekleri kullanmak çözüm olabilir.
Konu Akışı Transaction Kavramı İzolasyon Seviyeleri ve Concurrency Triggerlar 26
Ders:Trigger larla Çalışmak Trigger'ları Kavramak Trigger Oluşturmak INSERT Trigger DELETE Trigger UPDATE Trigger INSTEAD OF Trigger DDL Trigger'lar Trigger Yönetimi 27
Ders: Trigger'ları Kavramak Trigger: Bir tablo üstünde tanımlanırlar INSERT UPDATE DELETE Olaylarından biri veya ikisi veya hepsine tepki verecek şekilde kodlanabilirler. Kendiliğinden devreye giren SP'lerdir. Biz çalıştıramayız Geriye değer döndüremezler. Bu nedenle kayıt gösterme maksatlı SELECT kullanılmamalıdır. Trigger çalışmadan önce bir Transaction açılır. Trigger içerisinde ROLLBACK ifadesi çalıştırılırsa son işlem geçersiz olur, ROLLBACK denmezse geçerli olur(otomatik COMMIT çalışır) İki Tip Trigger FOR(BEFORE) INSTEAD OF DİKKAT!: Her iki tip trigger da her bir kayıt için bir defa devreye girmez! Etkilenen bütün kayıtlar için toplu olarak bir defa devreye girer. SQL Server 2005 de dahil Row Based trigger yok(oracle-postgre.. de var!) 28
Hangi Durumlarda Trigger Birincil Anahtar Türetme Maksatlı IDENTITY() ve NEWID() sadece belli bir formatta PK türetebilir Constraint'lerin yetersiz olduğu yerlerde veri bütünlüğü öğesi olarak kodlanırlar. Karmaşık iş kuralları. (Örn.işlem gerçekleştiğinde e-mail atma vs.) Standart hata tanımlarının dışında bir hata mesajı türetmek için Farklı veritabanları arasında FK-PK çifti(bunu Constraint yapamaz) Veri Değişimlerini Kaydetmek maksatlı Hangi kaydı kim silmiş-değiştirmiş Şu Durumlarda Trigger Kullanılmamalı: Cascade Data Integrity artık Constraint'lerce denetlenebilmekte(ms SQL8.0+- Sybase7.0+) Bir DELETE-INSERT-UPDATE'ten kaç kaydın etkilendiğini bulmak için(select @@ROWCOUNT daha etkindir) 29
Sözde Tablolar Trigger'lar dışarıdan parametre alamazlar. Bir işlemden hangi satırların etkilendiğini bulmak için sözde tablolar kullanılır İki Sözde Tablo INSERTED DELETED tablosu kullanılır. Sözde tabloların şeması(sütun ve tipleri) son olarak kayıt eklenen-silinen-güncellenen tablo ile aynıdır. TABLO A Eklenen kayıtlar INSERT INTO A INSERTED tablosu INSERTED Tablosu DELETED Tablosu INSERT Trigger DELETE Trigger UPDATE Trigger Yeni Eklenen Kayıtlar - Kayıtların Güncellenen Halleri - Silinen Kayıtlar Kayıtların Değişmeden Önceki Hali 30
Basit bir Trigger Yazmak CREATE TRIGGER trigger_adi ON tablo_adi [WITH seçenekler] {FOR AFTER INSTEAD OF} {INSERT UPDATE DELETE [,UPDATE[,DELETE] } AS Otomatik çalışacak SQL İfadeleri GO Örnek: CREATE TRIGGER siparisgeldi ON tblsiparis FOR INSERT AS DECLARE @FaturaKod BIGINT, @msg VARCHAR(255) SELECT @FaturaKod=inserted.faturaKod FROM inserted SET @msg='yeni sipariş alındı: Fatura Kodu:' + CAST(@faturaKod AS VARCHAR(16)) EXEC master..xp_sendmail 'ygozudeli@verivizyon.com',@msg 31
DDL Trigger'lar INSTEAD OF türden olamazlar! Sunucu seviyeli ve veritabanı seviyeli olabilir CREATE TRIGGER SunucuDegisiklikKaydedici ON ALL SERVER FOR DDL_LOGIN_EVENTS AS GO CREATE TRIGGER TR$artikKullaniciYok ON DATABASE FOR CREATE_LOGIN AS GO DROP TRIGGER trigger_ismi ON ALL SERVER DROP TRIGGER trigger_ismi ON DATABASE 32
Ödev S.453-Veritabanı Atölyesi 1-2-3. Sorular S.484-Veritabanı Atölyesi 5-6.Sorular 33
Sonuç Veritabanı ortak zamanda erişimleri optimum yönetir. Verileri tutarlı ve kararlı saklar. Eş zamanlı erişimlere karşı verileri tutarlı saklamanın maliyeti vardır:kilitlenmeler 34