|
TRANSACTION – EXCEPTION(Try-Catch)
Yukarıdaki tablo yapısında bir satış
eklendiğinde hem Satis hemde SatisUrun tablosuna kayıt eklenmelidir.Fakat burada
şöyle bir problem vardır.Satis tablosuna ilgili kayıt eklendikten sonra,satılan
ürünler SatisUrun tablosuna eklenecektir.Fakat bu ekleme sırasında hata oluşur ise
son durum şöyledir;Satis tablosuna kayıt eklenmiş fakat satışa ait herhangi bir
ürün SatisUrun tablosuna eklenmemiştir.Bu ise istenilen bir durum değildir.İstiyoruz
ki madem ki bir satışda hem Satis hemde SatisUrun tablosuna kayıt(lar) eklenecek
bu durumda öyle bir şey yapalım ki,eğer ekleme sırasında hata oluşursa,hiç bir işlem
yapmasın,yaptıklarınıda geri alsın,hata oluşmaz ise,işlemeye devam etsin.
İşte bunu sağlamanın yolu transaction
kullanmaktır.
ÖRNEK: Yukarıdaki örnekte Satis,SatisUrun tablolarına yapılacak kayıtları transaction
içinde gerçekleştirerek tutarsızlığı engelleyelim.
|
CREATE PROCEDURE
SatisEkle(
@id
INT OUTPUT,
@personel
NVARCHAR(50),
@tarih
SMALLDATETIME
)
AS
BEGIN
INSERT INTO Satis
VALUES(@personel,@tarih)
SET @id =
@@IDENTITY
END
CREATE PROCEDURE
SatisUrunEkle(
@satisId
INT,
@urunId
INT,
@miktar
INT,
@birimFiyat
INT
)
AS
BEGIN
INSERT INTO SatisUrun
VALUES(@satisId,@urunId,@miktar,@birimFiyat)
END
|
Öncelikle tablolara kayıt ekleyecek
2 adet Stored Procedure gerçekleştirdik.Ardından Transaction içinde çalışacak olan
Stored Procedure’ümüzü gerçekleştirelim;
|
ALTER PROCEDURE
SatisYap
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
DECLARE @satisId
INT
DECLARE @tarih
SMALLDATETIME
SET @tarih
= GETDATE()
EXEC SatisEkle @satisId
OUTPUT,'Veli Ermis',@tarih
EXEC SatisUrunEkle @satisId,6,4,5
EXEC SatisUrunEkle @satisId,2,7,2
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
SELECT ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage;
END CATCH
END
|
Burada sırasıyla 6 ve 2 ID’sine
sahip kayıtlar SatisUrun tablosuna eklenmeye çalışılmaktadır.2 veya 6 ID’sine sahip
bir ürün,Urun tablosunda yok ise Exception oluşacaktır.Fırlatılan exception BEGIN-END-CATCH
bloğunda yakalanacaktır.ROLLBACK komutuyla birlikte transaction iptal edilecek ve
bütün işlemler geri alınacaktır.Hiç bir hata oluşmadığı durumda da COMMIT komutu
işletilecek ve yapılan bütün değişiklikler tablolara kalıcı bir şekilde işlenecektir.
CATCH bloğu içine gelindiyse muhakkak
hata oluşmuştur.Oluşan hataya dair bilgileri almak için bir SELECT yazılmıştır.Bu
SELECT içinde sırasıyla şu bilgiler elde edilmektedir;
|
ERROR_NUMBER
|
Hata Numarası
|
|
ERROR_SEVERITY
|
Hatanın şiddeti
|
|
ERROR_STATE
|
Hata durumu
|
|
ERROR_PROCEDURE
|
Hatanın oluştuğu stored procedure veya trigger
|
|
ERROR_LINE
|
Hatanın oluştuğu Satır
|
|
ERROR_MESSAGE
|
Hata Mesajı
|
Aşağıdaki durumlarda TRY bloğu içerisinde
oluşan hatalar yakalanmaz;
·
SEVERITY değeri 10 veya 10’dan az ise yani uyarı ve bilgi amaçlı ise
·
O an açık olan bağlantı,SEVERITY değeri 20 veya üstü olduğundan dolayı kesilir ise,yani
hata çok şiddetli olursa
·
Veri tabanı yönetici tarafından o anki oturum kapatılırsa
Not: @@Trancount değeri o anki aktif transaction sayısını döndürür.
|