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