क्या हमें C # कोड में और साथ ही संग्रहीत कार्यविधि में लेनदेन को संभालने की आवश्यकता है


14

क्या हमें वास्तव में c # के साथ-साथ डेटाबेस स्टोर प्रक्रिया दोनों में लेनदेन से निपटने की आवश्यकता है

सी#:

Using(transaction with transaction scope)
{
     Execute stored proc;
     Transaction. Complete;
}

SQL संग्रहीत कार्यविधि:

Create process
As
Begin try
    Begin transaction
    Commit
End try
Begin catch
    Rollback
End catch

जवाबों:


20

सबसे पहले , आपको अपनी सभी प्रक्रियाओं में हमेशा उचित लेन-देन करना चाहिए, ताकि कोई फर्क नहीं पड़ता कि उन्हें ऐप कोड द्वारा बुलाया जाता है, किसी अन्य प्रक्रिया द्वारा, व्यक्तिगत रूप से एक ऐड-हॉक क्वेरी में, SQL एजेंट नौकरी या कुछ अन्य माध्यमों से। । लेकिन एकल डीएमएल स्टेटमेंट, या कोड जो कोई संशोधन नहीं करता है, को एक स्पष्ट लेनदेन की आवश्यकता नहीं है । इसलिए, मैं जो सिफारिश कर रहा हूं वह है:

  • हमेशा TRY / CATCH संरचना है ताकि त्रुटियों को ठीक से बुदबुदाया जा सके
  • वैकल्पिक रूप से नीचे दिए गए कोड में 3 ट्रांजेक्शन हैंडलिंग टुकड़े शामिल करें यदि आपके पास कई डीएमएल स्टेटमेंट हैं (चूंकि एक स्टेटमेंट अपने आप में एक लेनदेन है)। फिर भी, कुछ अतिरिक्त कोड जोड़ने के बाहर जहां इसकी विशेष आवश्यकता नहीं है, यदि कोई एक सुसंगत टेम्पलेट रखना पसंद करता है, तो यह 3 लेन-देन से संबंधित IF ब्लॉकों में रखने के लिए चोट नहीं पहुंचाता है। लेकिन उस मामले में मैं अभी भी सिलेक्ट-ओनली (यानी केवल पढ़ने के लिए) प्रोक्स के लिए 3 ट्रांजेक्शन से संबंधित आईएफ ब्लॉक नहीं रखने की सलाह दूंगा।

2 या अधिक डीएमएल स्टेटमेंट करते समय, आपको निम्नलिखित की तर्ज पर कुछ का उपयोग करने की आवश्यकता होती है (जो सिंगल डीएमएल ऑपरेशंस के लिए भी किया जा सकता है, यदि कोई सुसंगत होना पसंद करता है):

CREATE PROCEDURE [SchemaName].[ProcedureName]
(
    @Param  DataType
    ...
)
AS
SET NOCOUNT ON;
DECLARE @InNestedTransaction BIT;

BEGIN TRY

    IF (@@TRANCOUNT = 0)
    BEGIN
        SET @InNestedTransaction = 0;
        BEGIN TRAN; -- only start a transaction if not already in one
    END;
    ELSE
    BEGIN
        SET @InNestedTransaction = 1;
    END;

    -- { 2 or more DML statements (i.e. INSERT / UPDATE / DELETE) }

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
        COMMIT;
    END;

END TRY
BEGIN CATCH

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
        ROLLBACK;
    END;

    DECLARE @ErrorMessage   NVARCHAR(4000) = ERROR_MESSAGE(),
            @ErrorState     INT = ERROR_STATE(),
            @ErrorSeverity  INT = ERROR_SEVERITY();

    -- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
    RETURN;

END CATCH;

केवल 1 डीएमएल स्टेटमेंट या सिर्फ एक सेलेक्ट करते समय, आप बस निम्नलिखित के साथ दूर हो सकते हैं:

CREATE PROCEDURE [SchemaName].[ProcedureName]
(
    @Param  DataType
    ...
)
AS
SET NOCOUNT ON;

BEGIN TRY

    -- { 0 or 1 DML statements (i.e. INSERT / UPDATE / DELETE) }

END TRY
BEGIN CATCH

    DECLARE @ErrorMessage   NVARCHAR(4000) = ERROR_MESSAGE(),
            @ErrorState     INT = ERROR_STATE(),
            @ErrorSeverity  INT = ERROR_SEVERITY();

    -- optionally concatenate ERROR_NUMBER() and/or ERROR_LINE() into @ErrorMessage

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState);
    RETURN;

END CATCH;

दूसरा , आपको ऐप लेयर में लेन-देन तभी करना चाहिए जब आपको 1 से अधिक क्वेरी / संग्रहित प्रक्रिया निष्पादित करने की आवश्यकता हो और उन्हें सभी को एक परमाणु ऑपरेशन में समूहीकृत करना हो। एक ही करना एक SqlCommand.Execute___कोशिश / पकड़ में होना चाहिए, लेकिन लेन-देन में नहीं।

लेकिन, क्या यह केवल एक कॉल करते समय ऐप लेयर में ट्रांजेक्शन करने में चोट करता है ? यदि इसके लिए MSDTC (Microsoft डिस्ट्रिब्यूटेड ट्रांजैक्शन कोऑर्डिनेटर) की आवश्यकता होती है, तो स्पष्ट रूप से आवश्यकता नहीं होने पर ऐप लेयर पर ऐसा करना सिस्टम पर थोड़ा भारी पड़ता है। व्यक्तिगत रूप से, मैं ऐप लेयर-आधारित लेन-देन से बचना पसंद करता हूं जब तक कि यह बिल्कुल आवश्यक नहीं है क्योंकि यह अनाथ लेनदेन की क्षमता में कटौती करता है (यदि प्रतिबद्ध या रोलबैक करने से पहले ऐप कोड के साथ कुछ गलत हुआ)। मैंने यह भी पाया है कि यह कभी-कभी डिबगिंग को कुछ स्थितियों को थोड़ा और कठिन बना देता है। लेकिन उस से किया जा रहा ने कहा, मैं कुछ भी नहीं दिख रहा है तकनीकी रूप से गलत भी जब एक ही बनाने एप्लिकेशन परत पर लेन-देन से निपटने procकहते हैं; फिर, एक एकल डीएमएल स्टेटमेंट का अपना लेनदेन है और इसे किसी भी स्तर पर किसी भी स्पष्ट लेनदेन से निपटने की आवश्यकता नहीं है

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