2009-07-23 14 views
52

मैं समझता हूं कि अपडेट की एक जोड़ी को समन्वयित करने के लिए एक लेनदेन कैसे उपयोगी हो सकता है। जो मैं समझ नहीं पा रहा हूं वह लेन-देन में एकल कथन लपेट रहा है, जो मैंने कभी देखा है का 9 0% है। असल में, वास्तविक जीवन कोड में, मेरे अनुभव में यह तर्कसंगत रूप से संबंधित लेन-देन की श्रृंखला को खोजने के लिए मेरे अनुभव में अधिक आम है, लेकिन प्रत्येक लेनदेन में लपेटा नहीं जाता है।एक ही कथन के आसपास लेनदेन क्या करता है?

एमएस-एसक्यूएल में, लेनदेन में एकल चयन, एकल अपडेट, एकल आवेषण या सिंगल डिलीट लपेटने से कोई फायदा होता है?

मुझे संदेह है कि यह अंधविश्वास प्रोग्रामिंग है।

उत्तर

45

यह कुछ भी नहीं करता है। सभी व्यक्तिगत एसक्यूएल स्टेटमेंट्स ((नो लॉग, या ट्रंकेट टेबल के साथ थोक सम्मिलन जैसे दुर्लभ अपवादों के साथ) स्वचालित रूप से "लेनदेन में" हैं, चाहे आप स्पष्ट रूप से ऐसा कहें या नहीं .. (भले ही वे लाखों पंक्तियों को सम्मिलित, अद्यतन या हटा दें) ।

संपादित करें: @ के आधार पर नीचे फिलिप की टिप्पणी ... काटना टेबल एसक्यूएल सर्वर के वर्तमान संस्करण, यहां तक ​​कि थोक आवेषण और लेन-देन में लॉग में कुछ डेटा लिख ​​सकता हूँ, हालांकि के रूप में ज्यादा नहीं अन्य कार्यों के रूप में करते हैं। एक लेनदेन संबंधी परिप्रेक्ष्य से महत्वपूर्ण भेद यह है कि इन अन्य प्रकार के संचालन में, आपके डेटाबेस टेबल में डेटा संशोधित किया जा रहा है, यह उस स्थिति में लॉग में नहीं है जो इसे वापस घुमाने की अनुमति देता है।

इसका मतलब यह है कि डेटाबेस में डेटा को डेटा में किए गए परिवर्तन लेनदेन लॉग में लॉग इन होते हैं ताकि ऑपरेशन विफल होने पर उन्हें पूर्ववत किया जा सके।

एकमात्र फ़ंक्शन जो "प्रारंभ लेनदेन", "कमिट लेनदेन" और "रोलबैक लेनदेन" आदेश प्रदान करता है, वह आपको एक ही लेनदेन में दो या दो से अधिक व्यक्तिगत SQL कथन डालने की अनुमति देता है।

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

एक मूर्ख स्थिरता थोड़ा मन की हौआ है,
थोड़ा द्वारा बहुत अच्छा लगा राजनेता और दार्शनिक और divines

+3

आपको पुष्टि करनी चाहिए, हां, यह अंधविश्वास प्रोग्रामिंग है। =) –

+0

@ चार्ल्स, MySQL के बारे में क्या? – Pacerier

+1

@Pacerier, मैं MySQL में धाराप्रवाह नहीं हूं, लेकिन अगर अन्य उत्पाद संबंधित उत्पादों से उनके उत्पाद ने इस संबंध में अलग-अलग व्यवहार किया है तो मुझे झटकेदार लगेगा। नोएसक्यूएल जैसे नए गैर-रिलेशनल डेटाबेस उत्पादों में से एक, एक अलग प्रतिमान के तहत काम कर सकता है, लेकिन मैं शर्त लगाता हूं कि MySQL समान है। –

2

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

यही वह है जो आपको चाहिए या नहीं।

उदाहरण के लिए, आप बाहरी दुनिया को प्रारंभिक परिणाम दिखाना चाहते हैं जबकि अभी भी उन्हें लॉक रखना है।

इस मामले में, यदि आप किसी अन्य लेन-देन जिसमें लॉक अनुरोध स्थानों से पहले पहले एक, करता है इस प्रकार रेस स्थिति

अंतर्निहित लेनदेन प्रतिबद्ध या बाद DML बयान पूरा करता है या विफल रहता है वापस तुरंत लुढ़का कर रहे हैं परहेज शुरू करते हैं।

+0

आह, सूक्ष्म अंतर। लेकिन यह वास्तव में स्पष्ट लेनदेन का लाभ नहीं है, मुझे लगता है कि स्पष्ट लेनदेन लॉक एकल कथन लेनदेन एक अतिरिक्त हार/खोने की स्थिति होगी - कम प्रदर्शन और कम समेकन, शायद मिलीसेकंड के लिए। – MatthewMartin

+1

@ मैथ्यूमार्टिन: मैंने लाभ या कमियों के कुछ भी नहीं कहा, मैंने अभी अंतर को समझाया। लेनदेन प्रदर्शन के बारे में सब कुछ नहीं हैं। इंस्टेस के लिए, आप अभी भी बाहरी दुनिया को प्रारंभिक परिणाम दिखाना चाहते हैं जबकि अभी भी उन्हें लॉक रखना है। इस मामले में, आप एक और लेनदेन शुरू करते हैं जो पहले व्यक्ति से पहले लॉक अनुरोध करेगा, इस प्रकार दौड़ की स्थिति से परहेज करेगा। इस मामले में आपको अभी भी एक ही कथन को लेनदेन में लपेटने की जरूरत है। – Quassnoi

+0

एसक्यूएल सर्वर वास्तविक नेस्टेड लेनदेन का समर्थन नहीं करता है। एक और शुरू करना एक बुरा विचार है। http://www.sqlskills.com/BLOGS/PAUL/post/A-SQL- सर्वर- डीबीए-myth-a-day-(2630)-nested-transactions-are-real.aspx – IamIC

5

चार्ल्स ब्रेताना ने कहा, "यह कुछ नहीं करता" - जो कुछ भी पहले से किया गया है उसके अलावा कुछ भी नहीं।

कभी एक संबंधपरक डेटाबेस की "एसीआईडी" आवश्यकताओं के बारे में सुनें? वह "ए" परमाणु है, जिसका अर्थ यह है कि या तो कथन पूरी तरह से काम करता है, या यह नहीं करता है - और कथन पूरा होने पर, कोई अन्य प्रश्न उस क्वेरी से प्रभावित डेटा पर किया जा सकता है। BEGIN ट्रांज़ेक्शन/COMMIT कई बयानों द्वारा किए गए कार्यों के लिए इस लॉकिंग कार्यक्षमता को "विस्तारित करता है", लेकिन यह एकल कथन में कुछ भी नहीं जोड़ता है।

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

मैं यहां भी अलगाव स्तर का नाम छोड़ दूंगा। इसके साथ झगड़ा व्यक्तिगत आदेशों को प्रभावित करेगा, लेकिन ऐसा करने से अभी भी एक घोषित-लेनदेन-लपेटा गया क्वेरी "स्टैंड-अलोन" क्वेरी से अलग तरीके से प्रदर्शन नहीं करेगी। (ध्यान दें कि वे मल्टी-स्टेटमेंट घोषित लेन-देन के साथ बहुत शक्तिशाली और बहुत खतरनाक हो सकते हैं।) ध्यान दें कि "नोलॉक" प्रविष्टियों/अपडेट/डिलीट पर लागू होता है - उन कार्रवाइयों को हमेशा ताले की आवश्यकता होती है।

+0

@ फिलिप, थैक्स, आपकी टिप्पणी का शोध करने में, मैंने पाया कि चीजें 'थोक सम्मिलन' के लिए बदल गई हैं क्योंकि मैंने पिछली बार इस कार्यक्षमता (एसक्यूएल 7 या एसक्यूएल 2 के) की समीक्षा की है ... –

+0

लेकिन कोड से एक स्पष्ट लेनदेन के बिना एक ही कमांड में निष्पादित दो स्टैंड-अलोन प्रश्न डेटाबेस में दो अंतर्निहित लेनदेन के रूप में निष्पादित होंगे, जिसका मतलब अलगाव स्तर और गंदे/लिखित डेटा के संदर्भ में है। – Henrik

2

एक संभावित बहाना यह है कि एकल कथन अन्य एसक्यूएल का एक समूह ट्रिगर्स के माध्यम से चलाने का कारण बन सकता है, और वे वहां कुछ खराब होने के खिलाफ सुरक्षा कर रहे हैं, हालांकि मुझे उम्मीद है कि किसी भी डीबीएमएस को सामान्य ज्ञान होना चाहिए पहले से ही इसी तरह के लेनदेन का उपयोग करें।

दूसरी बात यह है कि मैं सोच सकता हूं कि कुछ एपीआई आपको ऑटोोकॉमिट को अक्षम करने की अनुमति देते हैं, और अगर कोई ऐसा करता है तो कोड लिखा जाता है।

+1

एसक्यूएल सर्वर ट्रिगर्स डीएमएल कोड के एक अंतर्निहित लेनदेन के अंदर चलाते हैं जो उन्हें लात मारता है। और हाँ, एमएस एसक्यूएल आपको ऑटोोकॉमिट बंद करने की अनुमति देता है। देखें: http://msdn.microsoft.com/en-us/library/aa259220(SQL.80).aspx –

3

मेरे लिए, एक लेनदेन में एक ही कथन को लपेटने का मतलब है कि यदि मैं कहता हूं, तो मैन्युअल निष्पादित करते समय एक WHERE क्लॉज भूल जाता है, एक बार अद्यतन स्टेटमेंट। उसने मुझे कुछ बार बचा लिया है।

उदा।

-------------------------------------------------------------- 
CREATE TABLE T1(CPK INT IDENTITY(1,1) NOT NULL, Col1 int, Col2 char(3)); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 
INSERT INTO T1 VALUES (101, 'abc'); 

SELECT * FROM T1 


-------------------------------------------------------------- 
/* MISTAKE SCENARIO  (run each row individually) */ 
-------------------------------------------------------------- 
BEGIN TRAN YOUR_TRANS_NAME_1; /* open a trans named YOUR_TRANS_NAME_1 */ 
    UPDATE T1 SET COL2 = NULL; /* run some update statement */ 
    SELECT * FROM T1;  /* OOPS ... forgot the where clause */ 
ROLLBACK TRAN YOUR_TRANS_NAME_1; /* since it did bad things, roll it back */ 
    SELECT * FROM T1;  /* tans rolled back, data restored. */ 



-------------------------------------------------------------- 
/* NO MISTAKES SCENARIO (run each row individually) */ 
-------------------------------------------------------------- 

BEGIN TRAN YOUR_TRANS_NAME_2; 
    UPDATE T1 SET COL2 = 'CBA' WHERE CPK = 4; /* run some update statement */ 
    SELECT * FROM T1;    /* did it correctly this time */ 

COMMIT TRAN YOUR_TRANS_NAME_2   /* commit (close) the trans */ 

-------------------------------------------------------------- 

DROP TABLE T1 

-------------------------------------------------------------- 
+2

शायद मेरा प्रश्न स्पष्ट नहीं था। मैं कोड का जिक्र कर रहा था जैसे: ट्रैन शुरू करें; अद्यतन foo set col1 = null; ट्रैन प्रतिबद्ध करें; जिसे एक बैच के रूप में निष्पादित किया जाता है। यह कई कोड अड्डों में एक बहुत ही आम पैटर्न है जिसे मैंने बनाए रखा है और यह देखने के लिए भी आम है कि जब आप एक मौजूदा ऐप उत्सर्जित करते हैं तो एसक्यूएल का पता लगाते हैं। आप एक इंटरैक्टिव प्रक्रिया का वर्णन कर रहे हैं जो दो अलग-अलग चरणों में किया जाता है। – MatthewMartin

संबंधित मुद्दे