T-SQL Transaction – Mustafa Alkan Kişisel Blog Sitesi
Veritabanı sistemlerini yüzeysel kullanan geliştiriciler için çok basit gelen işlemler aslında mimari olarak geri planda bir çok iş sürecinin doğru yürütülmesiyle meydana gelmektedir. Bu iş süreçleri veritabanı motoru tarafından yönetilir. Ancak, depoladığımız veriyle ilgili işlemlerin bütünlüğü tamamen bize, yani geliştiriciye aittir.
Örneğin, birbiriyle ilişkili bir sorgu yapısı var ve biz bu kodların tamamının doğru çalışması halinde başarılı bir işlem gerçekleştirmiş olacak isek, bu durumda herhangi bir parça işlemin başarısız olması halinde diğer yapılan tüm işlemlerin geri alınması mantıklı olacaktır. Bu işleme en gerçekçi ve bilinen örnek bankacılık işlemleri gösterilebilir. Bir havale yapmak için gerekli tüm işlemleri yaptınız ve X hesabından Y hesabına 10 tl para göndereceksiniz. Bu işlemin programsal olarak yapılabilmesi için sizin hesabınızdaki bakiyenin UPDATE ile güncellenerek azaltılması, gönderilen hesabın bakiyesinin de UPDATE ile güncellenerek alınan miktar kadar artırılması gerekir. Ancak teknolojide herşey doğru gitmeyebilir. Bu işlemler sırasında herhangi bir hata olursa sizin hesabınızdan 10 tl düşülecek, ancak karşı tarafın hesabı güncellenerek bakiye artırımı gerçekleşmeyebilir.
Veritabanı mimarisinde bu tür iş süreci(transaction) gerektiğinde uyulması gereken prensibe ACID (Atomicity,Consistency, Isolation, Durability) denir.
Şimdi ACID’i sırasıyla inceleyelim.
Transaction işleminin ana özelliği olarak açıkladığımız bölünemezlik prensibini yansıtır. Bir transaction bloğu yarım kalamaz. Yarım kalan transaction bloğu veri tutarsızlığına neden olur. Ya tüm işlemler gerçekleştirilir, ya da transaction başlangıcına geri döner. Yani transaction’ın gerçekleştirdiği tüm değişiklikler geri alınarak gerçekleşmeden önceki haline döner.
Bölünemezlik kuralının alt yapısını oluşturduğu bir kuraldır. Transaction veri tutarlılığı sağlamalıdır. Yani bir transaction içerisinde güncelleme işlemi gerçekleştiyse ve ya kalan tüm işlemler de gerçekleşmeli ya da güncelle işlemi de geri alınmalıdır. Bu veri tutarlılığı açısından çok önemlidir.
Her transaction veritabanı için bir istek paketidir. Bir istek paketi (transaction) tarafından gerçekleştirilen değişiklikler tamamlanmadan bir başka transaction tarafından görülememelidir. Her transaction ayrı olarak işlenmelidir. Transaction’ın tüm işlemleri gerçekleştikten sonra bir başka transaction tarafından görülebilmelidir.
– Dayanıklılık (Durability)
Transaction’lar veri üzerinde karmaşık işlemler gerçekleştirebilir. Bu işlemlerin bütününü güvence altına almak için transaction hatalara karşı dayanıklı olmalıdır. SQL Server’da meydana gelebilecek sistem sorunu, elektrik kesilmesi, işletim sisteminden ya da farklı yazılımlardan kaynaklanabilecek hatalara karşı hazırlıklı ve dayanıklı olmalıdır.
Bilgisayar bilimlerinde imkansız diye bir şey yoktur. Bir sistemin hata vermesi yüzlerce sebebe bağlı olabilir. Örneğin; geçtiğimiz yıllarda büyük bir GSM operatörünün veri merkezinin bulunduğu binaya sel basması sonucu veri kaybı yaşamışlardı. Bu durum olasılığı düşük gibi görünebilir. Ancak bahsi edilen konu önemli veriler olunca, hesaplanması gereken olasılıkların sınırı yoktur. Tüm hata olasılıklarına karşı dayanıklı bir sistem geliştirilmelidir.
Transaction yönetimi için kullanılan dört farklı ifade vardır. Bu ifadeler ile transaction başlatılabilir (BEGIN), işlemler geri alınabilir (ROLLBACK), transaction bitirilebilir (COMMIT) ya da kayıt noktaları (SAVE) oluşturulabilir.
Transactıon’ı Başlatmak: BEGIN TRAN
Transaction’ın başlangıcını belirtir. Bu kısımdan sonraki tüm işlemler transaction’ın bir parçasıdır. İşlem sırasında oluşabilecek olası sorunlarda geri alma ya da transaction’ın sonlandırılması gerçekleştirilebilir.
BEGIN TRAN[SACTION] [transaction_ismi | @transaction_degiskeni]
Transactıon’ı Tamamlamak: COMMIT TRAN
Transaction’ın tamamlandığını ve gerçekleştirilen transaction işlemlerinin kalıcı olarak veritabanına yansıtılması için kullanılır. Transaction tarafından etkilenen tüm değişiklikler, işlemlerin tamamı gerçekleşmese bile, bu işlemden sonra kalıcı hale gelir.
COMMIT işleminden sonra gerçekleşen değişikliklerin geri alınması için, bu işlemleri geri alacak yeni bir transaction oluşturulmalıdır. Örneğin; bir transaction ile, nümerik bir sütun üzerinde 10 birim azaltma işlemi yapıldı ise, bu işlemi geri almak için aynı sütun üzerinde 10 birim artırma işlemi yapacak yeni bir transaction oluşturulmalıdır.
COMMIT TRAN[SACTION] [transaction_ismi | @transaction_degiskeni]
Transactıon’ı Geri Almak : ROLLBACK TRAN
Transaction’ın gerçekleştirdiği tüm işlemleri geri almak için kullanılır. Yani, yapılan tüm işlemler transaction’ın başlangıcındaki haline geri döner. Verilerdeki değişikliklerin anında kalıcı olarak veritabanına yansıtılmadığını belirtmiştik. ROLLBACK ile gerçekleştirilen tüm işlemler geriye alınarak transaction sonucunun tutarlılığı garanti edilir.
ROLLBACK işlemi, oluşturduğunuz transaction mimarisine bağlı olarak, kayıt noktalarına (save points) geri dönüş için de kullanılabilir.
ROLLBACK TRAN[SACTION] [transaction_ismi | kayit_noktasi_ismi
| @transaction_degiskeni | @kayit_noktasi_degiskeni]
Sabitleme Noktaları: SAVE TRAN
ROLLBACK işlemi transaction’da en başa dönmek için kullanılır. Bazen de belirli bir noktaya kadar gerçekleşen işlemlerin geçerli kalması istenebilir. Bu işlemlerden sonra gerçekleşecek işlemler için ROLLBACK’e ihtiyaç duyulabilir. Sabitleme noktaları oluşturulması, transaction içerisinde en başa dönmek yerine, belirlenen bir işlem noktasına dönmek için kullanılır
SAVE TRAN[SACTION] [ kayit_noktasi_ismi | @kayit_noktasi_degiskeni ]
Transaction işlemleri için en uygun örnekler bankacılık ve gsm operatörlerinin veritabanı işlemleridir. Karmaşık ve bir çok iş parçacığı ile gerçekleşen sayısız işlemden oluşan bu tür uygulamalarda iş bloklarının doğru planlanması ve kullanılması önemlidir.
Bir banka veritabanında kullanıcı hesaplarını tutan ve farklı iki banka hesabı arasında havale işlemini gerçekleştirmek için bir uygulama oluşturalım.
Banka müşterilerinin hesap bilgilerini tutan basit bir tablo oluşturalım.
AccountID CHAR(10) PRIMARY KEY NOT NULL,
AccountID : Hesap sahibine özel benzersiz değer.
FirstName : Hesap sahibinin adı.
LastName : Hesap sahibinin soyadı.
Branch : Şube kodu.
Balance : Hesap bakiyesi.
VALUES('0000065127','Cihan','Özhan', 489, 10000),
('0000064219','Ali','Veli', 489, 500),
('0000068233','Hasan','Hseyin', 252, 5844);
Sorgulama için gerekli veriyi eklediğimize göre, artık ilgili prosedürümüzü oluşturarak transaction’ımızı yönetmeye başlayabiliriz.
CREATE PROC sp_MoneyTransfer(
@retVal INT OUT
DECLARE @inControl MONEY;
SELECT @inControl = Balance FROM Accounts WHERE AccountID = @SenderID;
IF @inControl >= @Amount
WHERE AccountID = @SenderID
WHERE AccountID = @PurchaserID
SET @retVal = -1;
Prosedürün aldığı parametreleri açıklamak gerekirse;
PurchaserID : Alıcı hesabın ID’si
SenderID : Gönderen hesabın ID’si
Amount : Gönderilecek tutar
retVal : Prosedür içerisinden geriye değer dönmeyi sağlayan OUT parametre. İşlem başarısız olursa -1 değeri döndürecek.
Şimdi, Cihan Özhan’ın Ali Veli’ye 500 tl göndermesini sağlayacak prosedür çağrımını yapalım.
DECLARE @rVal INT;
EXEC sp_MoneyTransfer '0000064219','0000065127',500, @rVal out;
Bu tür prosedürlerde bir çok işlem kontrol edilir. Ancak biz sadece gönderen kişinin hesabında göndermek istediği kadar miktar olup olmadığını kontrol ettik.
Kaynak : Yazılımcılar İçin İleri Seviye T-SQL Programlama
26/11/2014 Mustafa ALKAN	Sql Server, SQL SERVER TRANSACTION, T-Sql, T-SQL Transaction, Transact-Sql, Transaction	Yorum bırakın