2012-08-06 12 views
7

मैंने हाल ही में एक अजीब समस्या में भाग लिया है, ओरेकल डेटाबेस में प्रोग्रामिंग: एक क्रमिक लेनदेन के अंदर, मैं एक द्रव्यमान सम्मिलित करता हूं (INSERT ... चुनें), और तुरंत बाद में, परिवर्तित तालिका पर एक चयन के साथ एक कर्सर खोलें। मैंने माना कि इस कर्सर में नई डाली गई पंक्तियां शामिल होंगी, लेकिन, मेरे आश्चर्य के लिए, इसकी सामग्री अनियमित होती है, कभी-कभी सभी नई डाली गई पंक्तियों और कभी-कभी केवल एक सबसेट भी शामिल होती है।ओरेकल: धारावाहिक लेनदेन में डालने के तुरंत बाद चुनें

मैंने कर्सर खोलने से पहले इस समस्या को हल करके हल किया है, लेकिन व्यवहार ने मुझे परेशान किया है। क्या एक ही लेनदेन के अंदर एक डालने के बाद चयन कर सकते हैं, अंतःक्रियात्मक प्रतिबद्धता के बिना, वास्तव में भरोसा किया जा सकता है? या यह व्यवहार किसी भी तरह से लेनदेन से संबंधित है?

फॉलोअप: जब एक प्रतिलिपि प्रस्तुत करने योग्य परीक्षण का मामला बनाने का प्रयास कर, मैं सिर्फ इस व्यवहार प्राप्त करने में सक्षम एक बार मैं एक सूचकांक (प्राथमिक कुंजी सूचकांक इस मामले में, वास्तविक कोड पर यह एक नियमित रूप से सूचकांक था) जोड़ा गया था। शायद समस्या इंडेक्स बनाने में बिताए समय में निहित है, ताकि परिणाम वास्तव में परिणामों को पुनर्प्राप्त करने के लिए एक अपूर्ण अनुक्रमणिका का उपयोग कर सकें? वैसे भी, यहाँ एक प्रतिलिपि प्रस्तुत करने योग्य परीक्षण का मामला है:

-- Create empty source table 
CREATE TABLE TEST_CASE_1 AS 
    (SELECT 'CONTENT' AS CONTENT 
    FROM DUAL 
    WHERE 1 = 2) 

-- Add primary key 
ALTER TABLE TEST_CASE_1 
ADD CONSTRAINT TEST_CASE_1_PK PRIMARY KEY (CONTENT); 

-- Create empty destination table 
CREATE TABLE TEST_CASE_2 AS 
    (SELECT 'CONTENT' AS CONTENT 
    FROM DUAL 
    WHERE 1 = 2) 

-- Example of faulty code 
BEGIN 

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

    -- Populate with 100.000 rows (I used ALL_OBJECTS but any source of 100.000 rows is good) 
    INSERT INTO TEST_CASE_1 
    (SELECT ROWNUM 
    FROM ALL_OBJECTS 
    WHERE ROWNUM <= 100000); 

    INSERT INTO TEST_CASE_2 
    (SELECT * 
    FROM TEST_CASE_1 
    WHERE CONTENT > 0); 

    COMMIT; 

END; 

इस उदाहरण में, मैं TEST_CASE_2 भी 100,000 पंक्तियों की उम्मीद करेंगे। इस टेस्ट केस को पुन: उत्पादित करना (लोड-फ्री डेटाबेस में), मैंने लगभग 400-500 पंक्तियां डालीं। लेन-देन को धारावाहिक के रूप में सेट करने वाले बयान को हटाकर, मैंने सही 100,000 पंक्ति गणना प्राप्त की।

+0

क्या आप कर्सर को उसी डेटाबेस सत्र में खोल रहे हैं जब आप सम्मिलित कर रहे हैं? आप यह काम कहां कर रहे हैं - वास्तव में डेटाबेस में या क्लाइंट एप्लिकेशन से - और यदि बाद वाले में आपके पास कनेक्शन पूलिंग है, और आप (कभी-कभी) दो कार्यों के लिए एक अलग कनेक्शन प्राप्त कर रहे हैं? –

+0

उसी सत्र में कर्सर खोला जा रहा है। मूल रूप से कर्सर को डेटाबेस में खोला गया था और उसके बाद एक .NET निष्पादन योग्य में पुनरावृत्त किया गया था, लेकिन समस्या को अलग करने के लिए मैंने उस प्रक्रिया का एक संस्करण बनाया जो डेटाबेस के अंदर कर्सर को फिर से चालू करता था, और समस्या बनी रही - वास्तव में ऐसा करने से पहले मैं नहीं कर सका ' खुद को यह विश्वास दिलाएं कि समस्या डालने के बाद चयन में थी। – user1578874

+0

ऐसा नहीं होना चाहिए; [डॉक्स] से (http://docs.oracle.com/cd/E11882_01/server.112/e25789/consist.htm#sthref1189) 'क्रमबद्ध अलगाव स्तर में, लेनदेन लेनदेन के समय केवल परिवर्तनों को देखता है - क्वेरी-शुरू नहीं हुआ और लेनदेन द्वारा किए गए परिवर्तन ', इसलिए आपको अपने स्वयं के परिवर्तन देखना चाहिए। मुझे लगता है कि आपके विशिष्ट संस्करण में एक बग हो सकता है। प्रतिबद्धता अलगाव स्तर को थोड़ा व्यर्थ बना देता है। क्या आप एक पुन: उत्पन्न परीक्षण केस पोस्ट कर सकते हैं? –

उत्तर

8

यह एक बग प्रतीत होता है; अगर आपको ओरेकल की समर्थन वेबसाइट तक पहुंच मिली है तो नोट 1455175.1 पर देखें, जो कि 8i की तारीख है। सूचीबद्ध कुछ बग संख्याएं हैं (75 9 2038 - 'सिक्योरिज़ेबल में नई अंतर्निहित पंक्ति के चयन/अद्यतन से सशक्त रूप से अविश्वसनीय डेटा', 636301 9) लेकिन वे 440317 के डुप्लिकेट के रूप में बंद हो गए हैं ('इस्लामी लेवल सर्जिकल कारणों को चुनने वाली पंक्तियों पर कोई डेटा नहीं मिला इन्टरेट के बाद '), जो अभी भी खुला है और विकास द्वारा जांच की जा रही है - भले ही इसे मूल रूप से संस्करण 7 (!) के खिलाफ उठाया गया हो।

आपको लगता है कि यह पीके से संबंधित है। सूचीबद्ध वर्कअराउंड हैं:

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

आप जानते हैं कि पहला वर्कअराउंड पहले से प्रभावी है, और मुझे नहीं लगता कि दूसरा या तीसरा आपकी मदद करेगा? आप दूसरे डालने के लिए चयन करने के लिए /*+ FULL(TEST_CASE_1) */ संकेत जोड़कर चौथे स्थान पर आज़मा सकते हैं।

मुझे 11.2.0.2 (लिनक्स) में त्रुटि नहीं मिली है, हालांकि मुझे बग को ठीक करने का सुझाव देने वाला कुछ भी नहीं मिला है; और मेरे पास 11.1 पर्यावरण नहीं है जिस पर कोशिश करने के लिए - इसलिए मैं यह जांच नहीं कर सकता कि आखिरी काम-आसपास इस परीक्षण मामले पर लागू होता है।

एक नोट है कि आप 11 जी में इसके बजाय ORA-08177 प्राप्त कर सकते हैं। मुझे यह समस्या थी अगर मैंने टेबल बनाने के तुरंत बाद अज्ञात ब्लॉक चलाया, या यदि मेरे पास बहुत सारी पंक्तियां डाली गईं, जो पीके से संबंधित प्रतीत होती है। This previous question प्रासंगिक हो सकता है।

ऐसा लगता है कि यह एक समस्या बनी रहेगी, इसलिए यदि कामकाज आपकी मदद नहीं करता है तो आपको पुनर्विचार की आवश्यकता हो सकती है यदि आपको वास्तव में अलगाव स्तर को बदलने की आवश्यकता है; और यदि आप करते हैं तो आपको बेहतर जवाब प्राप्त करने के लिए ओरेकल के साथ सेवा अनुरोध उठाना पड़ सकता है।

+0

आपके पूर्ण उत्तर के लिए बहुत बहुत धन्यवाद! मैं जिस बग का अनुभव कर रहा हूं वह ओरेकल समर्थन में इस मुद्दे के अनुरूप प्रतीत होता है। मुझे खुशी है कि यह एक बग है क्योंकि हम अपने सिस्टम के बहुत छोटे लेकिन मिशन-महत्वपूर्ण अनुभाग के लिए धारावाहिक लेनदेन पर निर्भर हैं, और यदि ये धारावाहिक लेनदेन के लिए मानक अर्थशास्त्र थे, तो हमें शायद पूरे खंड को फिर से लिखना होगा।पहला कामकाज (जो मैंने उपयोग किया) मेरे विशेष परिदृश्य में ठीक है, लेकिन कार्यक्रम के अन्य हिस्सों में नहीं। मैं अपने टूलबॉक्स में वर्कअराउंड के पूरे शस्त्रागार को रखूंगा। – user1578874

+1

ऐसा लगता है कि यह बग * अभी भी * तय नहीं है; मैंने इसे विंडोज़ पर ओरेकल 12.1.0.1.0 के साथ पुन: पेश किया। –

+1

बस इसे ओरेकल 12.1.0.2.0 - 64 बिट लिनक्स पर मिला ... – Jakob

2

यह एक पुष्टि की गई बग है, और ओरेकल ने कहा कि वे इसे ठीक करने की योजना नहीं बनाते हैं।

ये लक्षण Serializable लेन-देन के कारण ज्ञात समस्याओं और बग 440,317 सही है के साथ निष्कर्ष के साथ पाया गया हैं: यहाँ मेरी सेवा अनुरोध के लिए उनकी प्रतिक्रिया (जनवरी 2015) से एक अंश है।

बग 440,317 - अलगाव स्तर serializable कारण नहीं के बाद डेटा सम्मिलित करें
बग 16,803,610 चयनित पंक्तियों पर पाया - पंक्तियां सम्मिलित जांच का उपयोग कर सम्मिलित किए serializable अलगाव स्तर TRANSAC में खो जाते हैं

इन दोनों बग्स प्रकाशित कर रहे हैं, तो आप देख सकते हैं एमओएस बग सर्च में विवरण।

विकास के अनुसार, बहुत लंबे इतिहास के साथ एक ही मुद्दे के लिए कई बग थे। डिज़ाइन को बदलने में आसान नहीं है, इसलिए इस सुविधा को बाहर करने के पल तक ठीक नहीं है, यह एक बहुत उपयोगी नहीं है।

विकास ने बग बंद कर दिया है कि कोड फिक्स संभव नहीं है।

समाधान का सुझाव दिया
आवेदन कोड modifiction हैं:
परिवर्तन तर्क का चयन
से पहले प्रतिबद्ध या न का उपयोग करने के लिए serializable
बिना आवेदन कोड संशोधन:
प्राथमिक कुंजी या अनुक्रमित का उपयोग न करें तालिका

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