SQL सर्वर जॉब में Transaction और Try-catch


9

SQL सर्वर जॉब के प्रत्येक चरण में हमारे पास DML ऑपरेशन होते हैं। अद्यतन सुनिश्चित करने के लिए / डालने के मामले में वापस लुढ़का दिया जाएगा कुछ गलत हो जाता है, मैं का डेटा संशोधनों लिपटे है हर कदम में TRY CATCHऔर TRANSACTIONब्लॉक:

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

क्या यह सुनिश्चित करता है कि त्रुटि के मामले में डेटा जोड़तोड़ को वापस लाया जाएगा? या अन्य विचारों को ध्यान में रखा जाना चाहिए?

ऐसा करने का कोई बेहतर तरीका होगा (विन्यासों आदि का उपयोग करके)?

धन्यवाद।

जवाबों:


7

मैं इसके बजाय अपवाद हैंडलिंग और नेस्टेड लेनदेन से एक पैटर्न की सिफारिश करूंगा :

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

यह पैटर्न अनचाहे लेनदेनXACT_STATE() से बचाव के लिए कैच ब्लॉक में जांच करता है :

अपरिहार्य लेनदेन और XACT_STATE
यदि TRY ब्लॉक में जनरेट की गई त्रुटि के कारण वर्तमान लेन-देन की स्थिति अमान्य हो जाती है, तो लेन-देन को एक uncommittable लेन-देन के रूप में वर्गीकृत किया जाता है। एक त्रुटि जो TRY ब्लॉक के बाहर लेन-देन को समाप्त कर देती है, एक TRY ब्लॉक के अंदर त्रुटि होने पर एक लेनदेन को एक अपरिहार्य स्थिति में प्रवेश करती है। एक अपरिवर्तनीय लेनदेन केवल रीड ऑपरेशंस या रोलबैक ट्रांजेक्शन कर सकता है। लेन-देन किसी भी लेनदेन-एसक्यूएल बयान को निष्पादित नहीं कर सकता है जो एक लेखन ऑपरेशन या एक कमिट ट्रांजेक्शन उत्पन्न करेगा। XACT_STATE फ़ंक्शन -1 का मान लौटाता है यदि लेन-देन को एक अनधिकृत लेनदेन के रूप में वर्गीकृत किया गया है। जब एक बैच खत्म हो जाता है, तो डेटाबेस इंजन किसी भी सक्रिय अप्राप्य लेनदेन को वापस ले लेता है। यदि कोई त्रुटि संदेश भेजा गया था जब लेन-देन एक अपरिहार्य स्थिति में प्रवेश किया, जब बैच समाप्त हो जाता है, तो क्लाइंट एप्लिकेशन को एक त्रुटि संदेश भेजा जाएगा। यह इंगित करता है कि एक uncommittable लेनदेन का पता लगाया गया था और वापस लुढ़का हुआ था।

आपका कोड उन @@TRANCOUNTस्थानों के लिए जाँच कर रहा है जहां यह 0 नहीं हो सकता है, यह सूचना संचार के संदेशों का उपयोग करता है और सफलता को संप्रेषित करने के लिए परिणाम सेट करता है, यह पुनर्प्राप्त करने योग्य त्रुटियों को नहीं संभालता है। आदर्श रूप से अपवादों को क्लाइंट को इस मामले में एजेंट की नौकरी के लिए प्रचारित किया जाना चाहिए (यानी आपका कैच फिर से बढ़ाना चाहिए)।


आपके उपयोगी उत्तर और शानदार वेबसाइट के लिए धन्यवाद! हालाँकि मैं सोच रहा हूँ कि क्या अभी भी मैं इस पैटर्न का उपयोग एक साधारण डीएमएल स्टेटमेंट (एक संग्रहीत खरीद नहीं) के साथ कर सकता हूँ? क्या हमें नीचे दिए गए लेनदेन को भी सहेजना है? (मेरे पास उपयोग करने के लिए स्टोर की खरीद नहीं है): लेनदेन usp_my_procedure_name सहेजें;
स्काई

2

जो आपको अच्छा लग रहा है, मुझे। आपके द्वारा लेन-देन को वापस करने के बाद मैं पाठ्यक्रम की जानकारी के साथ कुछ करने का सुझाव दूंगा। उदाहरण के लिए इसे लॉग पर लिखें।


1
आपके उत्तर के लिए धन्यवाद, क्या आप कृपया मुझे संकेत दे सकते हैं कि इसे लॉग में कैसे लिखें?
स्काई

3
यदि आप लॉग टेबल में त्रुटियां या डेटा लिखना चाहते हैं, तो रोलबैक करने से पहले, उस डेटा को कॉपी करें जिसे आप टेबल वेरिएबल में चाहते हैं (यह महत्वपूर्ण है कि आप टेबल वेरिएबल का उपयोग करें, एक टेम्प टेबल वापस रोल किया जाएगा।) फिर प्रदर्शन करें। रोलबैक, फिर लॉग चर तालिका में तालिका चर से डेटा डालें।
HLGEM
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.