यदि आपको त्रुटि संदेश 3902, स्तर 16 प्राप्त हो रहा है, जिसमें लिखा है, "COMMIT TRANSACTION अनुरोध में कोई संगत BEGIN TRANSACTION नहीं है", यह शायद इसलिए है क्योंकि आपके पास एक भटका हुआ COMMIT
है बयान।
आपको यह त्रुटि प्रबंधन को लागू करने, और यह भूल जाने के कारण हो सकता है कि आपने अपने कोड में कहीं और लेन-देन पहले ही कर दिया है या वापस ले लिया है।
त्रुटि का उदाहरण
त्रुटि प्रदर्शित करने के लिए यहां एक सरल उदाहरण दिया गया है:
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
परिणाम:
(7 rows affected) Msg 3902, Level 16, State 1, Line 2 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
यह तब होगा जब आपका SET IMPLICIT_TRANSACTIONS
OFF
है . नीचे देखें कि क्या होता है जब SET IMPLICIT_TRANSACTIONS
ON
है ।
त्रुटि प्रबंधन के कारण त्रुटि का उदाहरण
आपको यह त्रुटि प्रबंधन को लागू करने, और यह भूल जाने के कारण हो सकता है कि आपने अपने कोड में कहीं और लेन-देन पहले ही कर दिया है या वापस ले लिया है।
उदाहरण के लिए:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
COMMIT TRANSACTION;
परिणाम:
(1 row affected) (1 row affected) (1 row affected) Msg 3902, Level 16, State 1, Line 20 The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
इस मामले में, मेरे पास पहले से ही COMMIT TRANSACTION
था TRY
. में खंड मैथा। तो जब तक दूसरा COMMIT TRANSACTION
सामना हुआ था, लेन-देन पहले ही किया जा चुका था।
हम वही देखेंगे, भले ही लेन-देन में कोई त्रुटि आई हो, और उसे वापस ले लिया गया हो। रोलबैक लेन-देन को समाप्त कर देगा, और इसलिए, आगे COMMIT
. नहीं बयानों की आवश्यकता है।
इसलिए इस समस्या को ठीक करने के लिए, हम केवल अंतिम COMMIT TRANSACTION
. को हटा देंगे , और लेन-देन कोड इस तरह दिखेगा:
BEGIN TRANSACTION
BEGIN TRY
INSERT INTO Orders ( OrderId, OrderDate, CustomerId )
VALUES ( 5006, SYSDATETIME(), 1006 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 1, 1, 20, 25.99 );
INSERT INTO OrderItems ( OrderId, OrderItemId, ProductId, Quantity, ItemPrice )
VALUES ( 5006, 2, 7, 120, 9.99 );
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
अंतर्निहित लेनदेन
यदि आपके पास निहित लेनदेन सक्षम है, तो आपको पहले उदाहरण के लिए अलग परिणाम मिल सकते हैं।
अगर हम IMPLICIT_TRANSACTIONS
. सेट करते हैं करने के लिए ON
, यहाँ हमें क्या मिलता है:
SET IMPLICIT_TRANSACTIONS ON;
SELECT ProductName, ProductPrice FROM Products;
COMMIT TRANSACTION;
परिणाम:
+---------------------------------+----------------+ | ProductName | ProductPrice | |---------------------------------+----------------| | Left handed screwdriver | 25.99 | | Long Weight (blue) | 14.75 | | Long Weight (green) | 11.99 | | Sledge Hammer | 33.49 | | Chainsaw | 245.00 | | Straw Dog Box | 55.99 | | Bottomless Coffee Mugs (4 Pack) | 9.99 | +---------------------------------+----------------+ (7 rows affected)
कोई त्रुटि नहीं होती है।
ऐसा इसलिए है, क्योंकि कुछ टी-एसक्यूएल स्टेटमेंट चलने पर स्वचालित रूप से लेनदेन शुरू कर देते हैं। ऐसा लगता है जैसे उनके सामने एक अदृश्य BEGIN TRANSACTION
. था बयान।
जब IMPLICIT_TRANSACTIONS
OFF
है , ये कथन स्वचालित रूप से प्रतिबद्ध हैं। ऐसा लगता है जैसे वे एक अदृश्य COMMIT TRANSACTION
. द्वारा सफल हो गए हैं बयान। इस परिदृश्य में, लेन-देन स्वत:प्रतिबद्ध मोड में है।
जब IMPLICIT_TRANSACTIONS
ON
है , कोई अदृश्य COMMIT TRANSACTION
. नहीं है बयान। ये कथन अभी भी एक अदृश्य BEGIN TRANSACTION
. द्वारा प्रारंभ किए गए हैं , लेकिन उन्हें स्पष्ट रूप से समाप्त करने की आवश्यकता है।
एक निहित लेन-देन तब तक जारी रहता है जब तक कि यह या तो स्पष्ट रूप से प्रतिबद्ध या स्पष्ट रूप से वापस नहीं किया जाता है।
इसलिए, इस उदाहरण में, हमारा भटका हुआ COMMIT TRANSACTION
निहित लेनदेन को समाप्त करने के लिए वास्तव में कथन की आवश्यकता थी।