जेडीबीसी में स्पष्ट रूप से अक्षम करें, एसक्यूएल में उनका पता लगाएं, या डेटाबेस को आसानी से स्थिति में रखें


12

पृष्ठभूमि : मैं http://sqlfiddle.com (मेरी साइट) पर काम कर रहा हूं , और वहां संभवत: दुरुपयोग के एक अवसर को रोकने की कोशिश कर रहा हूं। मैं उम्मीद कर रहा हूं कि वर्तमान में मैं जिस समस्या का समाधान कर रहा हूं, उसके बारे में पूछकर, मैं अनजाने में संभावित दुरुपयोग को बदतर नहीं बना सकता, लेकिन आप क्या कर सकते हैं? मुझे आप लोगों पर भरोसा है।

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

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

फ़ॉलबैक विकल्प : यदि स्पष्ट कमिट को अक्षम करने के लिए JDBC को कॉन्फ़िगर करना संभव नहीं है, तो मैं निम्नलिखित बैकएंड में से प्रत्येक के लिए एक बैच को संसाधित करते समय स्पष्ट कमिट का पता लगाने के लिए समाधान के लिए खुला रहूंगा: SQL सर्वर, Oracle, MySQL और PostgreSQL।

SQL सर्वर के लिए, मैंने इस समाधान के बारे में सोचा: एक्सएमएल क्वेरी योजना के माध्यम से पार्स करें इससे पहले कि मैं इसे निष्पादित करूं, और इस XPath से मेल खाने वाली प्रविष्टि की उपस्थिति की जांच करें:

//*[@StatementType="COMMIT TRANSACTION"]

मुझे लगता है कि यह SQL सर्वर के लिए बहुत अच्छा काम करेगा। हालाँकि, यह दृष्टिकोण अन्य DB प्रकारों के लिए काम नहीं करता है। ओरेकल की एक्सएमएल निष्पादन योजना स्पष्ट रूप से लागू होने के लिए इस तथ्य का कोई संदर्भ नहीं है कि आप एक कमिटमेंट स्टेटमेंट चला रहे हैं (बल्कि यह केवल उन क्वेरी से निष्पादन प्लान आउटपुट को दोहराता है जो यह कर रहे हैं)। PostgreSQL और MySQL स्पष्ट रूप से आने के लिए सभी (XML या अन्यथा) पर कोई निष्पादन योजना आउटपुट प्रदान नहीं करते हैं।

यह मुझे "वचन" शब्द के लिए वास्तविक विवरण की जाँच करने के साथ छोड़ देता है। यह काम करेगा, सिवाय इसके सभी प्रकार के बदलाव संभव हो सकते हैं:

declare @sql varchar(50)
set @sql = 'com' + 'mit'
exec(@sql);

उपरोक्त SQL सर्वर (जो मैं काम कर सकता था) के लिए एक उदाहरण है, लेकिन मुझे लगता है कि Oracle, MySQL और PostgreSQL के लिए समान चीजें संभव होंगी। क्या मैं उस धारणा पर गलत हूं? शायद वे "गतिशील" बयानों की अनुमति नहीं देंगे? SQL फेल्ड का उपयोग करने के लिए स्वतंत्र महसूस करें (अधिमानतः नमूना स्कीमा या किसी अन्य व्यक्ति के काम पर होने की संभावना नहीं है) यह देखने के लिए कि क्या आप Oracle, MySQL और PostgreSQL में कुछ समान बना सकते हैं। यदि नहीं, तो शायद सरल स्ट्रिंग का पता लगाना उन लोगों के लिए काम कर सकता है।

फिर भी एक और संभावना

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

अपडेट करें

मैंने हाल ही में क्या सीखा है - यह वास्तव में PostgreSQL के साथ कोई समस्या नहीं है। लेन-देन ब्लॉक के भीतर जारी किए गए स्पष्ट रूप से लागू होने पर लागू नहीं होगा यदि वही ब्लॉक अंततः रोल-बैक (पोस्टग्रेज में) हो जाता है। तो Postgres के लिए हुर्रे!

एसओ पद के लिए फिल के लिंक के लिए धन्यवाद, मुझे लगता है कि मैं Oracle के लिए DEFERRABLE INITIALLY DEFERRED हैक का उपयोग कर सकता हूं, यह पूरा करने के लिए कि मैं क्या कर रहा हूं (यदि कोई त्रुटि जारी की जाती है, तो त्रुटि हो जाएगी, लेकिन मैं इसके साथ काम कर सकता हूं)। यह ओरेकल को संबोधित करना चाहिए। (मैंने सोचा कि एक पल के लिए नेस्टेड लेनदेन यहां काम कर सकते हैं, लेकिन ऐसा नहीं लगता है कि ओरेकल नेस्टेड लेनदेन का समर्थन करता है; वैसे भी मुझे ऐसा कुछ भी नहीं मिला जो इस तरह से काम करता हो)।

वास्तव में अभी तक MySQL के लिए एक समाधान नहीं है। नेस्टेड लेनदेन का उपयोग करने की कोशिश की, लेकिन वह काम नहीं करता है। मैं MySQL के लिए और अधिक कठोर दृष्टिकोणों के बारे में गंभीरता से सोच रहा हूं, जैसे कि या तो कुछ भी अनुमति नहीं देता है, लेकिन दाईं ओर का चयन करता है या प्रत्येक क्वेरी के बाद DB को पुन: छोड़ता / पुन: बनाता है। हालांकि न तो अच्छा लगता है।

संकल्प

इसलिए, मैंने अब SQL सर्वर और ओरेकल के लिए वर्णित समाधानों को लागू किया है, और जैसा कि मैंने उल्लेख किया है कि यह वास्तव में PostgreSQL के लिए कोई समस्या नहीं है। MySQL के लिए, मैंने क्वेरी पैनल को केवल बयानों तक सीमित रखने का कुछ दुर्भाग्यपूर्ण कदम उठाया है। MySQL के लिए DDL और DML को स्कीमा पैनल (बाईं ओर) में प्रवेश करना होगा। मुझे उम्मीद है कि यह बहुत पुरानी पहेलियों को नहीं तोड़ता है, लेकिन मुझे लगता है कि डेटा स्थिरता को सुनिश्चित करने के लिए बस यही करना है। धन्यवाद!


उल्लेख के लायक - मैंने "पूर्व-प्रतिबद्ध" ट्रिगर्स की तलाश में बहुत सारे शोध भी किए। ऐसा प्रतीत होता है कि वे मौजूद नहीं हैं, इसलिए दुर्भाग्य से यह एक विकल्प भी नहीं है।
जेक फेज़ल

2
Oracle के लिए, यह COMMITs को पकड़ने का एक अच्छा डरपोक तरीका लगता है: stackoverflow.com/a/6463800/790702 वह जो उल्लेख नहीं करता है वह यह है कि आपको अपने कोड में भी बाधा उल्लंघन को पकड़ने में सक्षम होना चाहिए, जिससे दूसरी स्थिति को रोका जा सके। होने वाली।
फिलो

@ केवल समस्या यह है कि मेरे पास (और वास्तव में नहीं चाहिए) प्रत्येक तालिकाओं की परिभाषा पर नियंत्रण है (जो बाएं पैनल पर परिभाषित हैं)। ताकि DEFERRABLE INITIALLY DEFERRED क्लॉज नहीं होगा (जब तक कि सभी टेबल के लिए स्वचालित रूप से ऐसा करने का कोई तरीका नहीं है - एक सिस्टम ट्रिगर के माध्यम से कहें जो टेबल स्टेटमेंट बनाने के लिए प्रतिक्रिया करता है? Ugh)
Jake Felel

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

2
@RickJames DDL MySQL और Oracle में निहित कमिट बनाता है, लेकिन PostgreSQL या SQL सर्वर में नहीं। मैंने इस पोस्ट के बाद जो मैकेनिज्म लागू किया है, वह चिंता का सबब है। जहाँ तक मनमाने ढंग से एसक्यूएल में प्रवेश करने की बात है - यह पूरी बात है!
जेक फेज़ल

जवाबों:


3

Oracle के लिए, यह COMMIT को पकड़ने का एक अच्छा तरीका है।

/programming//a/6463800/790702

वह जो उल्लेख नहीं करता है वह यह है कि आपको अपने कोड में बाधा उल्लंघन को पकड़ने में सक्षम होना चाहिए, जिससे होने वाली दूसरी स्थिति को रोका जा सके।


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

कोई चिंता नहीं। चैट में ड्रॉप करें और कहें :)
फिलो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.