SQL Server 2005 - Hızlı El Kitabı
Skip Navigation Links.

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.