संग्रहीत प्रक्रिया में “SET XACT_ABORT ON” का उपयोग करने का क्या लाभ है?


177

SET XACT_ABORT ONसंग्रहीत प्रक्रिया में उपयोग करने का क्या लाभ है ?


2
सुविधा के लिए msdn रेफरी: msdn.microsoft.com/en-us/library/ms188792.aspx
टिम एबेल

3
यह इसके बारे में एक बहुत अच्छा लेख है: sommarskog.se/error_handling/Part1.html
इंजीनियर

जवाबों:


231

SET XACT_ABORT ONSQL सर्वर को संपूर्ण लेनदेन को रोलबैक करने और रन-टाइम त्रुटि होने पर बैच को निरस्त करने का निर्देश देता है। यह आपको SQL Server के भीतर (जो डिफ़ॉल्ट XACT_ABORT OFFसेटिंग द्वारा कवर नहीं किया गया है ) के बजाय क्लाइंट एप्लिकेशन पर होने वाले कमांड टाइमआउट जैसे मामलों में शामिल करता है ।

चूंकि क्वेरी टाइमआउट लेन-देन को खुला छोड़ देगा, SET XACT_ABORT ONस्पष्ट लेनदेन के साथ सभी संग्रहीत प्रक्रियाओं में अनुशंसित है (जब तक कि आपके पास अन्यथा करने का कोई विशिष्ट कारण न हो) क्योंकि एक खुले लेनदेन के साथ कनेक्शन पर काम करने वाले आवेदन के परिणाम विनाशकारी होते हैं।

डैन गुज़मैन के ब्लॉग पर वास्तव में बहुत अच्छा अवलोकन है ,


41
तो यह डिफ़ॉल्ट रूप से क्यों नहीं है?
माइक डब्ल्यू।

1
यदि आपके पास BEGIN TRY- BEGIN CATCHऔर Sql में ब्लॉक के ROLLBACKसाथ XACT_ABORT अभी भी आवश्यक है BEGIN CATCH?
user20358

1
@ user20358 BEGIN TRY- BEGIN CATCHक्लाइंट एप्लिकेशन पर होने वाली टाइमआउट जैसी चीजों को नहीं पकड़ पाएगा, और कुछ SQL त्रुटियां भी उपलब्ध नहीं हैं, जो आपको एक खुले लेनदेन के साथ छोड़ देती हैं, जहां आप एक की उम्मीद नहीं करेंगे।
टॉम लिंट

37

मेरी राय में SET XACT_ABORT ON को SQL 2k5 में BEGIN TRY / BEGIN CATCH के अलावा अप्रचलित कर दिया गया था। Transact-SQL में अपवाद ब्लॉकों से पहले त्रुटियों को संभालना वास्तव में मुश्किल था और असंतुलित प्रक्रियाएं सभी बहुत सामान्य थीं (प्रक्रियाएं जो प्रविष्टि की तुलना में एक अलग @@ TRANCOUNT थी)।

Transact-SQL अपवाद को जोड़ने के साथ लेनदेन को ठीक से संतुलित करने की गारंटी देने वाली सही प्रक्रियाओं को लिखना बहुत आसान है। उदाहरण के लिए मैं अपवाद हैंडलिंग और नेस्टेड लेनदेन के लिए इस टेम्पलेट का उपयोग करता हूं :

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
go

यह मुझे परमाणु प्रक्रियाओं को लिखने की अनुमति देता है जो पुनर्प्राप्त करने योग्य त्रुटियों के मामले में केवल अपना काम रोलबैक करता है।

मुख्य मुद्दों में से एक Transact-SQL प्रक्रियाओं का सामना डेटा शुद्धता है : कभी-कभी प्राप्त पैरामीटर या तालिकाओं में डेटा केवल सादे गलत होते हैं, जिसके परिणामस्वरूप डुप्लिकेट कुंजी त्रुटियां, रेफ़रेन्शल कॉस्ट्रेन एरर, चैक अड़चन एरर वगैरह वगैरह आते हैं। आखिरकार, यह ठीक इन बाधाओं की भूमिका है, अगर ये डेटा शुद्धता त्रुटियां असंभव होंगी और सभी व्यावसायिक तर्क से पकड़े जाएंगे, तो बाधाएं सभी अप्रचलित होंगी (प्रभाव के लिए नाटकीय अतिशयोक्ति)। यदि XACT_ABORT चालू है, तो इन सभी त्रुटियों के परिणामस्वरूप संपूर्ण लेन-देन खो जाता है, अपवाद को ब्लॉक करने में सक्षम होने का विरोध करने के रूप में, जो अपवाद के रूप में इनायत से संभालते हैं। एक विशिष्ट उदाहरण एक INSERT करने की कोशिश कर रहा है और PK उल्लंघन पर अद्यतन करने के लिए पुन: प्रस्तुत कर रहा है।


9
क्लाइंट टाइमआउट को छोड़कर ... और मेरा विचार है कि SET XACT_ABORT SQL 2005 में अधिक प्रभावी है क्योंकि व्यवहार अधिक अनुमानित है: बहुत कम बैच गर्भपात की त्रुटियां।
gbn

7
मैं कुछ हद तक सहमत हूं, लेकिन मैं सभी घटनाओं के आसपास अपनी त्रुटि से निपटने की योजना बनाता हूं, क्योंकि मुझे पता है कि अगर कमांड टाइमआउट होता है तो मुझे डेवलपर डीबीए के रूप में दोष मिलेगा।
gbn

4
@RemusRusanu आप एक लंबे समय तक चलने वाले, सिंक्रोनस, डेटाबेस ऑपरेशन को कैसे संभालेंगे?
इयान बॉयड

5
MSDN दस्तावेज़ीकरण कहता है: "SQL सर्वर सहित अधिकांश OLE DB प्रदाताओं के खिलाफ अंतर्निहित या स्पष्ट लेनदेन में डेटा संशोधन विवरणों के लिए XACT_ABORT को चालू किया जाना चाहिए। एकमात्र विकल्प जहां यह विकल्प आवश्यक नहीं है यदि प्रदाता नेस्टेड लेनदेन का समर्थन करता है।" msdn.microsoft.com/en-us/library/ms188792(v=sql.120).aspx
नाथन

4
"मेरी राय में सेट XACT_ABORT पर प्रयास शुरू के अलावा द्वारा अप्रचलित बना दिया गया था / शुरू पकड़ने" - मैं तुम्हें सुनते हैं, लेकिन कृपया देखें sommarskog.se/error_handling/Part1.html
उलट अभियंता

22

MSDN का हवाला देते हुए :

जब SET XACT_ABORT चालू होता है, यदि कोई Transact-SQL कथन रन-टाइम त्रुटि उठाता है, तो संपूर्ण लेन-देन समाप्त हो जाता है और वापस चला जाता है। जब SET XACT_ABORT बंद होता है, तो कुछ मामलों में केवल Transact-SQL स्टेटमेंट जो त्रुटि उठाता है, उसे वापस ले लिया जाता है और ट्रांजेक्शन प्रोसेस हो जाता है।

व्यवहार में इसका मतलब यह है कि कुछ बयान विफल हो सकते हैं, लेन-देन को 'आंशिक रूप से पूरा' छोड़कर, और कॉल करने वाले के लिए इस विफलता का कोई संकेत नहीं हो सकता है।

एक सरल उदाहरण:

INSERT INTO t1 VALUES (1/0)    
INSERT INTO t2 VALUES (1/1)    
SELECT 'Everything is fine'

यह कोड XACT_ABORT OFF के साथ 'सफलतापूर्वक' निष्पादित करेगा, और XACT_ABORT ON ('INSERT INTO t2' के साथ एक त्रुटि के साथ समाप्त हो जाएगा, निष्पादित नहीं किया जाएगा और एक ग्राहक एप्लिकेशन एक अपवाद बढ़ाएगा)।

अधिक लचीले दृष्टिकोण के रूप में, आप प्रत्येक कथन (पुराने स्कूल) के बाद @@ ERROR की जांच कर सकते हैं, या TRY ... CATCH ब्लॉक (MSSQL2005 +) का उपयोग कर सकते हैं। जब भी कुछ उन्नत त्रुटि से निपटने का कोई कारण नहीं है, व्यक्तिगत रूप से मैं XACT_ABORT को सेट करना पसंद करता हूं।


8

क्लाइंट टाइमआउट और उन्हें संभालने के लिए XACT_ABORT के उपयोग के बारे में, मेरी राय में ग्राहक API में SqlClient जैसे टाइमआउट होने का कम से कम एक बहुत अच्छा कारण है, और वह है SQL सर्वर कोड में होने वाले गतिरोध से क्लाइंट एप्लिकेशन कोड की रक्षा करना। इस मामले में क्लाइंट कोड की कोई गलती नहीं है, लेकिन इसे सर्वर पर पूरा होने के लिए कमांड के इंतजार में हमेशा के लिए अवरुद्ध होने से बचाने के लिए है। इसके विपरीत, यदि क्लाइंट कोड को क्लाइंट कोड की सुरक्षा के लिए मौजूद होना है, तो क्या XACT_ABORT ON को क्लाइंट कोड से सर्वर कोड की सुरक्षा करनी है, अगर क्लाइंट कोड से अधिक समय लगता है तो ग्राहक को इंतजार करने की इच्छा होती है।


1

लेन-देन प्रबंधन में इसका उपयोग यह सुनिश्चित करने के लिए किया जाता है कि किसी भी त्रुटि के परिणामस्वरूप लेनदेन वापस हो जाए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.