Transaction ve Örnekler 12.DERS Transaction ve Örnekler BUKET DOĞAN
Haftanın Hedefi SQL server da Transaction kavramını anlama ve T-SQL kodlarını oluşturabilme Daha önce öğrenilen SQL deyimlerini Transaction yapısında kullanabilme
Transaction Geçen hafta Tetikleyiciler ve Hata kontrolü konularını inceledik. Bu hafta Transaction yapısını inceleyeceğiz Transaction, belirli işlemleri bir bütün halinde çalıştırmak için kullanılan bir yapıdır. Transaction ile birden çok komut bir blok halinde çalıştırılır ve tüm komutların başarılı olması halinde işlemler onaylanır. Eğer komutlardan bir tanesi bile başarısız olursa işlem iptal olur. "Ya hep, ya hiç" kuralı...
Transaction İlişkisel veri tabanı tasarımında birçok tablo birbirine bağımlı haldedir. Bir tablodaki kaydın silinmesi diğer tablodaki kayıtları da etkileyebilmektedir veya bir tabloya kayıt eklenmesi için başka bir tabloda buna ilişkin kaydın önceden eklenmiş olması gerekebilmektedir. Transaction işlemlerinin en çok kullanıldığı sistemler banka sistemleridir çünkü banka sistemleri güvenli olmak zorundadır ve hesap işlemlerinde oluşabilecek en küçük hatalar bile telafisi imkansız büyük problemlere yol açabilir.
ACID Kuralı 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ı
SQL Server'de Transaction Türleri
Harici(Explicit) Transaction Harici(Explicit) Transaction Herhangi bir dize ifade ACID'den birine gereksinim duyduğunda programcı başlatır. BEGIN TRAN <transaction_ismi> İfadeler COMMIT | ROLLBACK
Havale yapanın hesabından havale miktarını düşecek Havala yapılanın hesabına havale miktarını ekleyecek Aralarda hata oluştu ise geri alacak (TRY CATCH veya IF @@ERROR) Oluşmadı ise sabitleyip çıkacak
Örnek CREATE TABLE Hesap( id integer identity(1,1), TCKimlikNo varchar(11), Ad varchar(30), Hesap money)
Buket’den vahdete para gönderilecek BEGIN TRY UPDATE dbo Buket’den vahdete para gönderilecek BEGIN TRY UPDATE dbo.Hesap SET Bakiye-=100 WHERE TCKimlikNo='23456789101' RAISERROR('Elektrikler Kesildi',16,2) UPDATE dbo.Hesap SET Bakiye+=100 WHERE TCKimlikNo='12345678910' END TRY BEGIN CATCH PRINT 'Beklenmedik bir hata olustu' END CATCH Eksiltme işlemi gerçekleşti fakat ekleme işlemi tamamlanmadı. Ortada bir para kaybı söz konusu. Nerede bu para?
Örnek "BEGIN TRAN" ile "transaction" işlemini başlatıyoruz. ("BEGIN TRANSACTION" da yazabilirdik.) Ard arda, tek bir işlemmiş gibi çalışmasını istediğim kod bloğumu yazdıktan sonra, "transaction" işlemini "COMMIT TRAN" (işlemi doğrulama anlamı var) ile sonlandırıyorum. "COMMIT TRAN" komutunu görene kadar, işlemlerimde hata olsa da olmasa da, işlem sonuçlarım tabloya yansımayacaktır. Daha sonra "try" bloğumu kapatıyorum. Bir hata ile karşılaşılması sonucunda "Catch" bloğu çalışacağından dolayı, "Catch" bloğunda da "ROLLBACK TRAN" komutu ile yapılan işlemleri geri alınmasını sağlıyoruz.
BEGIN TRY BEGIN TRAN UPDATE dbo BEGIN TRY BEGIN TRAN UPDATE dbo.Hesap SET Bakiye-=100 WHERE TCKimlikNo='23456789101' RAISERROR('Elektrikler Kesildi',16,2) UPDATE dbo.Hesap SET Bakiye+=100 WHERE TCKimlikNo='12345678910' COMMIT TRAN END TRY BEGIN CATCH PRINT 'Beklenmedik bir hata olustu' ROLLBACK TRAN END CATCH
SAVE TRAN Bir kişi bankaya gelsin ve adına bir hesap açılmasını, bu hesabına da arkadaşından havale yapılmasını istesin. Hesap oluşturmak demek, "Hesap" tablosuna bir kayıt "insert" edilmesi gerek . Daha sonra yukarıda yaptığımız eksiltme arttırma işlemleri. Peki bu işlemlerin hepsini "TRAN" blokları arasında yazarsam ne olur? Program akışı bir hata ile karşılaşırsa, hesap oluşturma işlemini de geri alacaktır. Ama biz hata ile karşılaşılması durumunda, hesap oluşturma işleminden sonraki işlemlerin geri alınmasını istiyoruz. Bunun için hesap oluştuktan sonra "transaction" işleminin kaydedilmesini sağlayabiliriz. Daha sonra hata olursa "Catch" bloğunda, transaction içinde tanımladığımız işlemlerin "ROLLBACK TRAN" diyerek geri alınmasını değil de, bu oluşturduğumuz kayıt noktasına kadar olan işlemlerin geri alınması için "ROLLBACK TRAN BakiyeOlustu" kod satırını kullanacağız.
Bu işlemleri daha dinamik hale getirmek için parametreleriyle birlikte bir "Strored Procedure" nesnesi oluşturup, kullanabiliriz. Gönderen ve alan kişilerin "TCKimlikNo" bilgilerini ve bir de gönderilmek istenen tutarı isteriz. "HavaleYap" adında bir "proc" tanımlıyoruz.
BEGIN TRY BEGIN TRAN INSERT dbo BEGIN TRY BEGIN TRAN INSERT dbo.Hesap (TCKimlikNo, Ad, Bakiye) VALUES ('34567891011', 'Mevlüt', 10000) COMMIT SAVE TRAN BakiyeOlustu UPDATE dbo.Hesap SET Bakiye-=100 WHERE TCKimlikNo='23456789101' RAISERROR('Elektrikler Kesildi',16,2) UPDATE dbo.Hesap SET Bakiye+=100 WHERE TCKimlikNo='12345678910' COMMIT TRAN END TRY BEGIN CATCH PRINT 'Beklenmedik bir hata olustu' ROLLBACK TRAN BakiyeOlustu END CATCH
Prosedür olarak Transaction CREATE PROC HavaleYap (@GonderenTC NCHAR(11),@AlanTC NCHAR(11),@Tutar MONEY) AS BEGIN TRY BEGIN TRAN UPDATE dbo.Hesap SET Bakiye-=@Tutar WHERE TCKimlikNo=@GonderenTC RAISERROR('Elektrikler Kesildi',16,2) UPDATE dbo.Hesap SET Bakiye+=@Tutar WHERE TCKimlikNo=@AlanTC COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN PRINT 'Beklenmedik bir hata olustu' END CATCH
HavaleYap @GonderenTC='23456789101', @AlanTC='12345678910', @Tutar=100 SELECT * FROM dbo.Hesap
COALESCE VE ISNULL SQL de boş ile NULL aynı şey değildir. Bazı durumlarda kolonun kesinlikle bir değer döndürmesini isteriz. Bunun için Null kontrolü yapmak zorunda kalırız. Buna en iyi örnek olarak matematiksel işlemleri verebiliriz. Hata almamak işlemin durumuna göre kontrol ederek uygun bir değerin gelmesini sağlarız. Boş değerlerle ilgili işlemlerde ISNULL yöntemi kullanılabilir; ISNULL() iki parametreyle çalışır: SELECT Adi, ISNULL(Sehir,'Sehir yok') FROM Personeller
NULL COALESCE ise birden fazla parametreyle çalışır ve eğer kolon null ise null olmayan ilk parametreyi getirir. SELECT Adi, COALESCE (Sehir, Bolge, 'Sehir yok') FROM Personeller SELECT Adi FROM Personeller WHERE Sehir is Null
http://korayduzgun. blogspot. com. tr/2012/04/t-sql-transaction http://korayduzgun.blogspot.com.tr/2012/04/t-sql-transaction.html http://www.verivizyon.com/Bm364/BM364-7.pdf