क्या मुख्य एसक्यूएल डेटाबेस में क्रिएट टेबल और अन्य टेबल स्टेटमेंट को रोल करना संभव है?


108

मैं एक कार्यक्रम पर काम कर रहा हूं जो डीडीएल जारी करता है। मैं जानना चाहूंगा कि क्या CREATE TABLEइसी तरह के डीडीएल को वापस लाया जा सकता है

  • postgres
  • माई एसक्यूएल
  • SQLite
  • और अन्य

बताएं कि प्रत्येक डेटाबेस डीडीएल के साथ लेनदेन को कैसे संभालता है।


बस इस सूत्र के पूरक, एच 2 भी SQL कमांड के अधिकांश के लिए लेन-देन संबंधी DDL बयान का समर्थन नहीं करता, के अनुसार इस
गेब्रियल पेम

जवाबों:


148

http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis PostgreSQL के दृष्टिकोण से इस मुद्दे का अवलोकन प्रदान करता है।

क्या इस दस्तावेज़ के अनुसार डीडीएल लेन-देन है?

  • PostgreSQL - हाँ
  • MySQL - नहीं; DDL एक अंतर्निहित कमिट का कारण बनता है
  • ओरेकल डेटाबेस 11 जी रिलीज़ 2 और उससे अधिक - डिफ़ॉल्ट रूप से, नहीं, लेकिन संस्करण-आधारित पुनर्वित्त नामक एक विकल्प मौजूद है
  • ओरेकल के पुराने संस्करण - नहीं; DDL एक अंतर्निहित कमिट का कारण बनता है
  • SQL सर्वर - हाँ
  • Sybase अनुकूली सर्वर - हाँ
  • DB2 - हाँ
  • सूचना - हाँ
  • फायरबर्ड (इंटरबेस) - हाँ

SQLite के साथ-साथ ट्रांजेक्शनल DDL भी दिखाई देता है। मैं SQLite में ROLLBACKएक CREATE TABLEबयान में सक्षम था । इसके CREATE TABLEप्रलेखन में किसी विशेष लेन-देन 'गोच' का उल्लेख नहीं है।


8
हालाँकि, sqlite के लिए डिफ़ॉल्ट पायथन ड्राइवर ट्रांसेक्शनल SQL को रोकता है। Bugs.python.org/issue10740
joeforker

तो जवाब है "हाँ, उन्हें वापस रोल किया जा सकता है, जब तक कि आप MySQL या ओरेकल के पुराने संस्करणों का उपयोग नहीं कर रहे हैं।"
rjmunro

नहीं, सूचीबद्ध लोगों के अलावा अन्य SQL डेटाबेस भी हैं।
जोफॉर्कर

3
Transactional DDL समर्थन जोड़ने के लिए MariaDB में एक खुला मुद्दा है: jira.mariadb.org/browse/MDEV-4259 । कृपया इसके लिए मतदान करें।
गिली

1
कुछ हद तक ALTER TABLESQLite का स्टेटमेंट भी लुढ़का हुआ है। दस्तावेज में इसका स्पष्ट उल्लेख नहीं है । वहाँ उल्लेख किया है कि कैसे एक लेनदेन के अंदर "उन्नत" परिवर्तन करने के लिए है।
थॉमस

32

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

CREATE INDEX ... CONCURRENTLY असाधारण है, यह समवर्ती अद्यतनों की अनुमति देते हुए एक तालिका में एक सूचकांक जोड़ने के लिए तीन लेनदेन का उपयोग करता है, इसलिए इसे स्वयं लेनदेन में नहीं किया जा सकता है।

इसके अलावा डेटाबेस मेंटेनेंस कमांड का VACUUMइस्तेमाल लेनदेन में नहीं किया जा सकता है।


मेरा तर्क है कि यदि मैं fooकिसी अन्य लेन-देन को छोड़ रहा हूं और उसे पुनः बनाए रख रहा हूं, तो मैं तालिका से चयन करने का प्रयास करता हूं , तो मैं पुराने संस्करण या त्रुटि के साथ ठीक हूं। मैं नए संस्करण के साथ ठीक नहीं हूं, क्योंकि यह अभी तक प्रतिबद्ध नहीं था, इसलिए मुझे इसे नहीं देखना चाहिए। मैं एक त्रुटि के साथ ठीक हूं, क्योंकि समवर्ती लेनदेन में किसी को भी लेनदेन को फिर से शुरू करने के लिए तैयार रहना होगा। यदि त्रुटियाँ आवश्यकता से अधिक बार होती हैं तो यह प्रदर्शन को कम कर सकती है, लेकिन यह अभी भी सही है।
Jan Hudec

1
@JanHudec: आपको नई तालिका का एक अप्रयुक्त संस्करण दिखाई नहीं देगा, केवल उस संपूर्ण लेन-देन का परिणाम जो इसे गिरा / पुन: बनाएगा। यानी एक टेबल को ड्रॉप, रीक्रिएट और रीपोप्लाइज करने वाला ट्रांजैक्शन प्रभावी रूप से उस टेबल से चुनने वाली अन्य प्रक्रियाओं को एटॉमिक wrt है। (लेकिन सब कुछ जैसे ही वे भी तालिका स्कीमा पढ़ने की कोशिश अवरुद्ध हो जाएगी)
araqnid

5

हालांकि यह कड़ाई से "रोलबैक" नहीं बोल रहा है, Oracle में FLASHBACK कमांड का उपयोग इन प्रकार के परिवर्तनों को पूर्ववत करने के लिए किया जा सकता है, यदि डेटाबेस को समर्थन देने के लिए कॉन्फ़िगर किया गया है।


5

लगता है कि अन्य उत्तर बहुत पुराने हैं।

2019 तक:

  • Postgres ने कई रिलीज़ के लिए Transactional DDL का समर्थन किया है।
  • SQLite ने कई रिलीज़ के लिए Transactional DDL का समर्थन किया है।
  • MySQL ने 8.0 के बाद से परमाणु डीडीएल का समर्थन किया है (जो 2018 में जारी किया गया था)।

1
एक ध्यान दें कि MySQL 8 में परमाणु DDL केवल परमाणु DDL बयानों को संदर्भित करता है, लेकिन लेन-देन संबंधी बयानों को नहीं। एक DDL कथन, परमाणु या नहीं, ज्यादातर अभी भी निहित प्रतिबद्धता का कारण बनता है और इस तरह एक और लेनदेन के भीतर निष्पादित नहीं किया जा सकता है (जैसे START TRANSACTION ... COMMIT;। इसलिए आप अभी भी एक लेनदेन में DDL विवरणों को वापस नहीं ला सकते हैं यदि एक ही लेनदेन में बाद वाला विफल हो जाता है । mysql.com/doc/refman/8.0/en/… )
फीता

4

MySQL के साथ ऐसा नहीं किया जा सकता है , यह बहुत गूंगा है, लेकिन सच है ... (स्वीकृत उत्तर के अनुसार)

"InnoDB में क्रिएट टेबल स्टेटमेंट को एक ट्रांजेक्शन के रूप में प्रोसेस किया जाता है। इसका मतलब यह है कि यूजर का एक रोलबैक उस ट्रांजेक्शन के दौरान यूजर द्वारा किए गए टेब स्टेटमेंट को पूर्ववत नहीं करता है।"

https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

कुछ अलग तरीके की कोशिश की और यह बस वापस रोल नहीं करेगा ..

चारों ओर काम बस एक विफलता झंडा सेट करने के लिए है और "ड्रॉप टेबल tblname" अगर एक प्रश्न में विफल रहा है ..


1
अरे नहीं। मैं यह पता लगाने की कोशिश कर रहा हूं कि पिछले एक घंटे के लिए किसी विशेष (बनाने) तालिका में विफल होने पर पहले बनाई गई तालिकाएं क्यों गायब नहीं होंगी। मैं MariaDB (XAMPP MySQL से MariaDB पर स्विच किया गया) का उपयोग कर रहा हूं, लेकिन मामला समान है। यह मूर्खतापूर्ण है: |
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.