Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर नेस्टेड लेनदेन में त्रुटियों को कैसे संभालें

इस लेख में, हम SQL सर्वर नेस्टेड लेनदेन, एक या कई लेनदेन के साथ एक लेनदेन ब्लॉक का पता लगाएंगे।

छवि नेस्टेड लेनदेन के एक साधारण मॉडल का वर्णन करती है।

आंतरिक लेनदेन एक संग्रहीत प्रक्रिया है जिसमें लेनदेन ब्लॉक होते हैं। MSDN अनुशंसा करता है कि "लेन-देन को यथासंभव छोटा रखें" जो पहले दृष्टिकोण के बिल्कुल विपरीत है। मेरी राय में, मैं नेस्टेड लेनदेन का उपयोग करने की अनुशंसा नहीं करता। फिर भी, कभी-कभी हमें कुछ व्यावसायिक समस्याओं को हल करने के लिए उनका उपयोग करना पड़ता है।

इस प्रकार, हम यह पता लगाने जा रहे हैं:

  • क्या होगा जब कोई बाहरी लेन-देन वापस ले लिया जाता है या प्रतिबद्ध हो जाता है?
  • जब कोई आंतरिक लेन-देन वापस ले लिया जाता है या प्रतिबद्ध हो जाता है तो क्या होगा?
  • नेस्टेड लेनदेन त्रुटियों को कैसे संभालें?

सबसे पहले, हम एक डेमो टेबल बनाएंगे और संभावित मामलों का परीक्षण करेंगे।

USE AdventureWorks
-----Create Demo Table----
CREATE TABLE CodingSightDemo
(NumberValue VARCHAR(20))

मामला 1:बाहरी और आंतरिक दोनों लेन-देन प्रतिबद्ध हैं।

TRUNCATE TABLE CodingSightDemo  
--<*************OUTHER TRANSACTION START*************>
BEGIN TRAN				   
INSERT INTO CodingSightDemo	
VALUES('One')				
--<INNER TRANSACTION START>
BEGIN TRAN 					
INSERT INTO CodingSightDemo 		
VALUES('Two') 			
COMMIT TRAN	 			
--< INNER TRANSACTION END>
INSERT INTO CodingSightDemo 								VALUES('Three')				  
COMMIT TRAN		
--<************* OUTHER TRANSACTION END*************>
SELECT * FROM CodingSightDemo

इस स्थिति में, सभी रिकॉर्ड सफलतापूर्वक तालिका में सम्मिलित किए जाते हैं। हमने माना कि प्रत्येक INSERT कथन एक त्रुटि नहीं लौटाता है।

मामला 2:बाहरी लेन-देन वापस ले लिया गया है , आंतरिक लेन-देन प्रतिबद्ध . है .

TRUNCATE TABLE CodingSightDemo  
--<*************OUTHER TRANSACTION START*************>
BEGIN TRAN				   
INSERT INTO CodingSightDemo	
VALUES('One')				
--<INNER TRANSACTION START>
BEGIN TRAN 					
INSERT INTO CodingSightDemo 		
VALUES('Two') 			
COMMIT TRAN	 			
--< INNER TRANSACTION END>
INSERT INTO CodingSightDemo VALUES('Three')				  
rollback TRAN		
--<************* OUTHER TRANSACTION END*************>
SELECT * FROM CodingSightDemo

जैसा कि आप देख सकते हैं, रिकॉर्ड तालिका में नहीं डाले गए हैं क्योंकि आंतरिक लेनदेन बाहरी लेनदेन का एक हिस्सा है। इस कारण से, आंतरिक लेन-देन वापस आ जाता है।

मामला 3:बाहरी लेन-देन प्रतिबद्ध है , आंतरिक लेन-देन वापस लुढ़का . है .

TRUNCATE TABLE CodingSightDemo  
--<*************OUTHER TRANSACTION START*************>
BEGIN TRAN				   
INSERT INTO CodingSightDemo	
VALUES('One')				
--<INNER TRANSACTION START>
BEGIN TRAN 					
INSERT INTO CodingSightDemo 		
VALUES('Two') 			
ROLLBACK TRAN	 			
--< INNER TRANSACTION END>
INSERT INTO CodingSightDemo VALUES('Three')				  
COMMIT TRAN		
--<************* OUTHER TRANSACTION END*************>
SELECT * FROM CodingSightDemo

इस मामले में, हमें एक त्रुटि मिली और तालिका में नवीनतम विवरण डाला गया। परिणामस्वरूप, कुछ प्रश्न उठते हैं:

  • हमें त्रुटि क्यों मिली?
  • नवीनतम INSERT स्टेटमेंट को टेबल में क्यों जोड़ा गया?

एक नियम के रूप में, रोलबैक ट्रान स्टेटमेंट वर्तमान सत्र में निष्पादित सभी खुले लेनदेन को वापस ले लेता है। हम एक प्रश्न नहीं लिख सकते क्योंकि यह एक त्रुटि लौटाएगा।

BEGIN TRAN
INSERT INTO CodingSightDemo	
VALUES('One')	
BEGIN TRAN
INSERT INTO CodingSightDemo	
VALUES('Two')	
ROLLBACK TRAN
ROLLBACK TRAN

हम जांच करेंगे कि यह नियम हमारे मामले को कैसे प्रभावित कर सकता है। रोलबैक ट्रान स्टेटमेंट आंतरिक और बाहरी लेन-देन को वापस रोल करता है। इस कारण से, COMMIT TRAN स्टेटमेंट चलाते समय हमें एक त्रुटि मिलती है क्योंकि कोई खुला लेनदेन नहीं होता है।

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

अगली स्क्रिप्ट के साथ, हम सेव पॉइंट्स का उपयोग करेंगे। वे लेन-देन में एक बिंदु को चिह्नित करते हैं और यदि आप चाहें, तो आप सभी डीएमएल (डेटा मैनिपुलेशन लैंग्वेज) स्टेटमेंट को चिह्नित बिंदु पर रोलबैक कर सकते हैं।

BEGIN TRY
BEGIN TRAN				   
INSERT INTO CodingSightDemo	
VALUES('One')				
--<INNER TRANSACTION START>
SAVE TRANSACTION innerTRAN
BEGIN TRY
BEGIN TRAN 					
INSERT INTO CodingSightDemo 		
VALUES('Two') 			
COMMIT TRAN
END TRY		
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN 
ROLLBACK TRANSACTION innerTRAN
PRINT 'Roll back occurs for inner tran'
END
IF XACT_STATE() <> 0
BEGIN 
COMMIT TRAN 
PRINT 'Commit occurs for firt open tran'
END
END CATCH
--< INNER TRANSACTION END>
INSERT INTO CodingSightDemo VALUES('Three')				  
COMMIT TRAN		
END TRY
BEGIN CATCH
BEGIN
IF XACT_STATE() <> 0
ROLLBACK TRAN 
PRINT 'Roll back occurs for outer tran'
END
END CATCH
--<************* OUTHER TRANSACTION END*************>
SELECT * FROM CodingSightDemo

आंतरिक लेन-देन में त्रुटि होने पर यह क्वेरी त्रुटि को संभाल लेगी। साथ ही, बाहरी लेनदेन सफलतापूर्वक किए जाते हैं। हालांकि, कुछ मामलों में, यदि आंतरिक लेनदेन में कोई त्रुटि होती है, तो बाहरी लेनदेन को वापस रोल करना होगा। इस मामले में, हम एक स्थानीय चर का उपयोग करेंगे जो आंतरिक क्वेरी त्रुटि स्थिति मान को बनाए रखेगा और पास करेगा। हम बाहरी क्वेरी को इस वैरिएबल मान के साथ डिज़ाइन करेंगे और क्वेरी इस प्रकार होगी।

--<*************OUTHER TRANSACTION START*************>
DECLARE @innertranerror as int=0
BEGIN TRY
BEGIN TRAN				   
INSERT INTO CodingSightDemo	
VALUES('One')				
--<INNER TRANSACTION START>
SAVE TRANSACTION innerTRAN
BEGIN TRY
BEGIN TRAN 					
INSERT INTO CodingSightDemo 		
VALUES('Two') 			
COMMIT TRAN
END TRY		
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN 
SET @innertranerror=1
ROLLBACK TRANSACTION innerTRAN
PRINT 'Roll back occurs for inner tran'
END
IF XACT_STATE() <> 0
BEGIN 
COMMIT TRAN 
PRINT 'Commit occurs for firt open tran'
END
END CATCH
--< INNER TRANSACTION END>
INSERT INTO CodingSightDemo VALUES('Three')	
if @innertranerror=0
BEGIN
COMMIT TRAN	
END
IF @innertranerror=1
BEGIN
ROLLBACK TRAN
END

END TRY
BEGIN CATCH
BEGIN
IF XACT_STATE() <> 0
ROLLBACK TRAN 
PRINT 'Roll back occurs for outer tran'
END
END CATCH
--<************* OUTHER TRANSACTION END*************>
SELECT * FROM CodingSightDemo

निष्कर्ष

इस लेख में, हमने नेस्टेड लेनदेन की खोज की और विश्लेषण किया कि इस प्रकार की क्वेरी में त्रुटियों को कैसे संभालना है। इस लेनदेन प्रकार के बारे में सबसे महत्वपूर्ण नियम रक्षात्मक प्रश्न लिखना है क्योंकि हमें बाहरी या आंतरिक लेनदेन में त्रुटि मिल सकती है। इस कारण से, हमें क्वेरी के त्रुटि प्रबंधन व्यवहार को डिज़ाइन करना होगा।

संदर्भ

नेस्टिंग लेन-देन

लेन-देन बचाएं


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर में किसी तालिका में इष्टतम अद्वितीय पहचानकर्ता कैसे खोजें:sp_special_columns

  2. कैसे ठीक करें "वैकल्पिक तालिका स्विच विवरण विफल"

  3. एसक्यूएल क्वेरी दो तालिकाओं के बीच अंतर वापस करने के लिए

  4. SQL सर्वर दो पूर्णांकों को विभाजित करने के परिणामों को बंद क्यों करता है?

  5. एक डेटाबेस मेल खाता (SSMS) हटाएं