2012-04-14 20 views
151

में लेनदेन का सही उपयोग मेरे पास 2 कमांड हैं और इन दोनों को सही तरीके से निष्पादित करने की आवश्यकता है या उनमें से कोई भी निष्पादित नहीं है। तो मुझे लगता है कि मुझे एक लेनदेन की आवश्यकता है, लेकिन मुझे नहीं पता कि इसका सही तरीके से उपयोग कैसे किया जाए।एसक्यूएल सर्वर 2008

निम्न स्क्रिप्ट के साथ समस्या क्या है?

BEGIN TRANSACTION [Tran1] 

INSERT INTO [Test].[dbo].[T1] 
    ([Title], [AVG]) 
VALUES ('Tidd130', 130), ('Tidd230', 230) 

UPDATE [Test].[dbo].[T1] 
    SET [Title] = N'az2' ,[AVG] = 1 
    WHERE [dbo].[T1].[Title] = N'az' 

COMMIT TRANSACTION [Tran1] 
GO 

insert आदेश निष्पादित लेकिन update आदेश एक समस्या है। यदि मैं उनमें से किसी को निष्पादन में कोई त्रुटि है तो मैं दोनों आदेशों को रोलबैक करने के लिए इसे कैसे कार्यान्वित कर सकता हूं? अगर लेन-देन में विफल रहता है

उत्तर

350

, आज़माएं/कैच ब्लॉक जोड़ें, लेन-देन सफल होता है यह परिवर्तन हो जाएंगे लेनदेन वापस लुढ़का है:

BEGIN TRANSACTION [Tran1] 

BEGIN TRY 

INSERT INTO [Test].[dbo].[T1] 
    ([Title], [AVG]) 
VALUES ('Tidd130', 130), ('Tidd230', 230) 

UPDATE [Test].[dbo].[T1] 
    SET [Title] = N'az2' ,[AVG] = 1 
WHERE [dbo].[T1].[Title] = N'az' 


COMMIT TRANSACTION [Tran1] 

END TRY 
BEGIN CATCH 
    ROLLBACK TRANSACTION [Tran1] 
END CATCH 

GO 
+13

यह एक अधिक उचित जवाब है। –

+9

अच्छा जवाब। जैसा लिखा है, यह त्रुटि संदेश को दबा देगा। इसे प्रदर्शित करने के लिए रोलबैक के बाद 'प्रिंट ERROR_MESSAGE()' जोड़ें। – atheaos

+1

'ट्रांज़ेक्शन [Tran1] '' TRY1' के अंदर नहीं रखा जाना चाहिए? वैसे भी - कोड का बहुत सरल और सुरुचिपूर्ण टुकड़ा। –

95

संग्रहीत प्रक्रिया की शुरुआत में एक SET XACT_ABORT ON रखना चाहिए निर्देश देने के लिए त्रुटि के मामले में स्वचालित रूप से रोलबैक लेनदेन के लिए एसक्यूएल सर्वर। यदि ओमिट या बंद करने के लिए सेट किया गया है तो प्रत्येक कथन के बाद @@ERROR का परीक्षण करने की आवश्यकता है या TRY ... CATCH rollback ब्लॉक का उपयोग करें।

+4

यह स्वीकार्य उत्तर कैसे हो सकता है? –

+4

क्योंकि यह [सही उत्तर] है (https://msdn.microsoft.com/en-us/library/ms188792.aspx): "जब SET XACT_ABORT बंद हो जाता है, कुछ मामलों में केवल ट्रांजैक्ट-एसक्यूएल कथन है कि उठाया गया त्रुटि वापस लुढ़का है और लेनदेन प्रसंस्करण जारी है। त्रुटि की गंभीरता के आधार पर, एसईटी XACT_ABORT बंद होने पर भी पूरा लेनदेन वापस लुढ़काया जा सकता है। OFF डिफ़ॉल्ट सेटिंग है। " मूल प्रश्न यह है कि INSERT क्यों होता है लेकिन अद्यतन वापस लुढ़का जाता है। ट्रे-कैच के साथ भी, आपका आईएनएसईआरटी पहले भाग जाएगा और प्रतिबद्ध होगा। हालांकि, अभी भी लचीलापन के लिए ट्रे-कैच का उपयोग किया जा सकता है। – 4AM

+1

दूसरे शब्दों में, आपका लेनदेन परमाणु नहीं है जब तक आप पहले XACT_ABORT सेट नहीं करते। – 4AM

22

आसान दृष्टिकोण:

CREATE TABLE T 
(
    C [nvarchar](100) NOT NULL UNIQUE, 
); 

SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error. 
SELECT * FROM T; -- Check before. 
BEGIN TRAN 
    INSERT INTO T VALUES ('A'); 
    INSERT INTO T VALUES ('B'); 
    INSERT INTO T VALUES ('B'); 
    INSERT INTO T VALUES ('C'); 
COMMIT TRAN 
SELECT * FROM T; -- Check after. 
DELETE T; 
संबंधित मुद्दे