SQL Server İşinde İşlem ve Try-catch


9

Bir SQL Server işinin her adımında DML işlemlerine sahibiz. Güncelleştirme sağlamak için / insert şey yanlış giderse durumda geri alınır, ben veri değişiklikleri sarılmış olan her adımda içinde TRY CATCHve TRANSACTIONbloklar:

BEGIN TRY
    BEGIN TRANSACTION

        [[INSERT/update statements]] ...

    IF @@TRANCOUNT > 0
    BEGIN
        COMMIT TRANSACTION
        PRINT 'Successful.'
    END

END TRY

BEGIN CATCH
    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

    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK TRANSACTION
        PRINT 'Unsuccessful.'
    END
END CATCH

Hata durumunda veri manipülasyonlarının geri alınmasını sağlıyor mu? Veya diğer hususlar dikkate alınmalıdır?

Bunu yapmanın daha iyi bir yolu olabilir mi (yapılandırmaları kullanarak, vb.)?

Teşekkür ederim.

Yanıtlar:


7

İstisna İşleme ve İç İçe İşlemler gibi bir model tavsiye ederim :

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch   
end

Bu model, teslim edilemeyen işlemlereXACT_STATE() karşı korunmak için catch bloğunda kontrol eder :

Taahhütsüz İşlemler ve XACT_STATE
TRY bloğunda üretilen bir hata, mevcut işlemin durumunun geçersiz kılınmasına neden olursa, işlem taahhüt edilemez bir işlem olarak sınıflandırılır. Bir TL bloğunun dışındaki bir işlemi normal olarak sonlandıran bir hata, bir TL bloğunun içinde hata oluştuğunda bir işlemin işlem edilemez duruma girmesine neden olur. Taahhütsüz bir işlem yalnızca okuma işlemleri veya GERİ DÖNÜŞ İŞLEMLERİ gerçekleştirebilir. İşlem, bir yazma işlemi veya bir COMMIT TRANSACTION oluşturacak herhangi bir Transact-SQL deyimini çalıştıramaz. Bir işlem taahhüt edilemez bir işlem olarak sınıflandırılmışsa, XACT_STATE işlevi -1 değerini döndürür. Bir toplu iş bittiğinde, Veritabanı Altyapısı etkin, taahhüt edilemez işlemleri geri alır. İşlem tamamlanamayan bir duruma girdiğinde hiçbir hata mesajı gönderilmezse, toplu iş bittiğinde, istemci uygulamasına bir hata iletisi gönderilir. Bu, taahhüt edilemez bir işlemin algılandığını ve geri alındığını gösterir.

Kodunuz @@TRANCOUNT0 olamaz yerlerde kontrol ediyor, başarılı iletişim için bilgi PRINT mesajları ve SELECT sonuç kümelerinin bir karışımını kullanır, kurtarılabilir hataları işlemez. İdeal olarak istisnalar müşteriye, bu durumda Agent işine yayılmalıdır (yani, yakalamanız yeniden yükseltilmelidir).


Faydalı cevabınız ve harika web siteniz için teşekkürler! Ancak ben hala bu desen basit bir DML deyimi (saklı bir proc değil) ile kullanabilirsiniz merak ediyorum? Ayrıca işlemi aşağıdaki gibi kaydetmemiz gerekiyor mu? (Kullanılacak bir mağaza procum yok): işlem usp_my_procedure_name kaydedin;
Sky

2

Sahip olduğun şey bana iyi geliyor. İşlemi geri aldıktan sonra, örneğin bir günlüğe yazdıktan sonra elbette bilgilerle bir şeyler yapmanızı öneririm.


1
Cevabınız için teşekkürler, lütfen bir günlüğe nasıl yazacağınıza dair bir ipucu verebilir misiniz?
Sky

3
Bir günlük tablosuna hata veya veri yazmak istiyorsanız, geri alma işlemini gerçekleştirmeden önce, istediğiniz verileri bir tablo değişkenine kopyalayın (tablo değişkeni kullanmanız önemlidir, geçici tablo geri alınır.) Sonra gerçekleştirin ardından, tablo değişkenindeki verileri günlük tablosuna ekleyin.
HLGEM
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.