2009-06-11 8 views
8

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

हमारी डेटाबेस समर्थन टीम ने पैरामीटर अधिकतम-प्रतिबद्धता-प्रसार-देरी 0 को बदलने के लिए सुझाव दिया है, क्योंकि यह 700 तक डिफ़ॉल्ट है। यह एक संभावित समाधान प्रतीत होता है लेकिन आखिरकार हमारी समस्या ठीक नहीं हुई।

एप्लिकेशन वेबस्पेयर पर चलता है और ओरेकल डेटाबेस को जेडीबीसी डेटासोर्स के रूप में कॉन्फ़िगर किया जाता है। हम ओरेकल 10.1 जी का उपयोग कर रहे हैं। एप्लिकेशन जावा 1.5 में लिखा गया है।

किसी भी मदद की सराहना की जाएगी।

संपादित करें: नमूना कोड

DataSource ds; // spring configured 

String sql = "INSERT INTO " + currentTable + " (" + stepId + ',' + stepEntryId + ", " + stepStepId + ", " + stepActionId + ", " + stepOwner + ", " + stepStartDate + ", " + stepDueDate + ", " + stepFinishDate + ", " + stepStatus + ", " + stepCaller + ") VALUES (?, ?, ?, null, ?, ?, ?, null, ?, null)"; 

Connection conn = ds.getConnection(); 
PreparedStatement stmt = conn.prepareStatement(sql); 
// set values 
stmt.executeUpdate(); 
// close connections 

// later on in the code... 
Connection conn = ds.getConnection(); 
PreparedStatement stmt = null; 
ResultSet rset = null; 

String sql = "SELECT " + stepId + ", " + stepStepId + ", " + stepActionId + ", " + stepOwner + ", " + stepStartDate + ", " + stepDueDate + ", " + stepFinishDate + ", " + stepStatus + ", " + stepCaller + " FROM " + currentTable + " WHERE " + stepEntryId + " = ?"; 
stmt = conn.prepareStatement(sql); 

stmt.setLong(1, entryId); 

rset = stmt.executeQuery(); 
//close connections 
+0

[ओरेकल दस्तावेज़ीकरण] से (http://download.oracle.com/docs/cd/B14117_01/server.101/b10755/initparams115.htm), ऐसा लगता है कि पैरामीटर 'max_commit_propagation_delay' केवल आरएसी सेटअप के लिए लागू होता है। क्या आप आरएसी इंस्टेंस से जुड़ रहे हैं? –

+0

क्या डेटा लेनदेन के हिस्से के रूप में किया जा रहा है? या पढ़ा? –

उत्तर

1

उपयोग एक ORM का उपयोग कर रहे हैं? यह कैश से चयन हो सकता है और परिवर्तन के बाद डीबी नहीं बना सकता है।

+0

हम एक ओआरएम का उपयोग नहीं कर रहे हैं, टेबल और एसक्यूएल स्टेटमेंट वास्तव में बुनियादी हैं और इन्हें केवल थोड़ी सी ट्रैकिंग जानकारी स्टोर करने के लिए उपयोग किया जाता है। – Andrew

+0

यदि संभव हो तो कोड खंड पोस्ट करें ... –

+1

यदि @Steve Broberg सुझाव काम नहीं करते हैं, तो आप उसी कनेक्शन का उपयोग करने का प्रयास कर सकते हैं –

6

डिफ़ॉल्ट रूप से, आपके द्वारा वर्णित व्यवहार असंभव होना चाहिए - प्रतिबद्ध लेनदेन में किए गए परिवर्तन सभी सत्रों में तुरंत उपलब्ध हो जाते हैं। हालांकि, अपवाद हैं:

  1. क्या आप COMMIT कमांड में किसी भी WRITE विकल्प का उपयोग कर रहे हैं? यदि आप नहीं हैं, तो अपने COMMIT_WRITE प्रारंभिक पैरामीटर के मान की पुष्टि करें। यदि या तो "लिखना बैच" या विशेष रूप से "लिखना बैच नौकाइट" का उपयोग कर रहा है, तो आप स्वयं को समवर्ती मुद्दों पर खोल सकते हैं। "लिखो बैच नौकाइट" आमतौर पर उन मामलों में उपयोग किया जाएगा जहां संभावित लेखन संबंधी मुद्दों की तुलना में आपके लेखन लेनदेन की गति अधिक महत्वपूर्ण है। अपने आरंभीकरण पैरामीटर "लिखने" वेरिएंट उपयोग कर रहा है, तो आप अपने प्रतिबद्ध (see COMMIT) में तत्काल खंड निर्दिष्ट करने के द्वारा एक सौदे के आधार पर यह ओवरराइड कर सकते हैं

  2. लेन-देन डेटा सेट लेनदेन से पहले लागू पढ़ने के लिए प्रयास कर रहा है है अन्य लेनदेन करने के लिए? क्रमबद्धता स्तर निर्दिष्ट करने के लिए सेट लेनदेन का उपयोग केवल पढ़ने के लिए या serializable में परिणाम होगा लेन-देन में कोई बदलाव नहीं है कि अन्य प्रतिबद्ध सत्र से पाए जाते हैं कि सेट लेनदेन के आह्वान के बाद हुई देखकर (see SET TRANSACTION)

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

यदि आपके पास डेटासोर्स क्लास के व्यवहार के लिए कोई नियंत्रण या दृश्यता नहीं है, तो आप बीमा प्राप्त करने के लिए नए अधिग्रहण कनेक्शन पर रोलबैक निष्पादित करने का प्रयास कर सकते हैं, इससे पहले कि यह पहले से स्थापित कोई लेनदेन लेनदेन नहीं है।

+0

+1 !!! मैंने COMMIT को तत्काल WAIT के अलावा भी नहीं माना था या लेनदेन अलगाव स्तर पढ़ा गया था अन्य के अलावा। – spencer7593

+0

आपको वापस पाने में देरी के लिए खेद है। मुझे नहीं लगता कि मैं प्रतिबद्धता के लिए किसी भी लेखन विकल्प का उपयोग कर रहा हूं। मैं जो भी जावा कनेक्शन क्लास को डिफ़ॉल्ट रूप से उपयोग कर रहा हूं, वही लेनदेन अलगाव सेटिंग के लिए जाता है। जावा क्लास के लिए यहां कुछ दस्तावेज लिंक दिए गए हैं: http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/DataSource.html http: //java.sun .com/j2se/1.5.0/docs/api/java/sql/Connection.html http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/connection.html – Andrew

4

यदि डीबीए टीम ने max_commit_propagation_delay पैरामीटर को संशोधित करने का प्रयास किया है, तो शायद इसका मतलब है कि आप एक आरएसी इंस्टेंस से कनेक्ट कर रहे हैं (i-e: कई अलग-अलग सर्वर एक एकल डेटाबेस तक पहुंच रहे हैं)।

उस स्थिति में, जब आप अपने जावा कोड में कनेक्शन बंद कर रहे हैं और फिर से खोल रहे हैं तो एक मौका है कि आपको एक अलग सर्वर द्वारा उत्तर दिया जाएगा। देरी पैरामीटर का मतलब है कि एक छोटा सा समय सीमा है जब दो उदाहरण बिल्कुल उसी बिंदु पर नहीं होंगे। जो जवाब आप प्राप्त कर रहे हैं वह समय पर एक बिंदु के अनुरूप है लेकिन यह सबसे वर्तमान नहीं हो सकता है।

केएम द्वारा प्रस्तावित अनुसार, सबसे आसान समाधान प्रतिबद्धता के बाद कनेक्शन को खोलना होगा।

वैकल्पिक रूप से, यदि आप व्यावहारिक हैं तो कनेक्शन बंद करने के बाद आप देरी भी जोड़ सकते हैं (यदि यह बैच नौकरी है और प्रतिक्रिया समय उदाहरण के लिए महत्वपूर्ण नहीं है)।

0

यह आरएसी के साथ एक समस्या की तरह लगता है, दो अलग-अलग उदाहरणों के कनेक्शन के साथ और एससीएन सिंक से बाहर है।

कामकाज के रूप में, डेटाबेस कनेक्शन को बंद करने और एक नया प्राप्त करने पर विचार न करें, लेकिन उसी कनेक्शन का पुन: उपयोग करें।

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

[परिशिष्ट]

उसके जवाब में, स्टीव Broberg (+1!) दिलचस्प विचार को जन्म देती है। मैं नहीं माना जाता था:

  • COMMIT से IMMEDIATE WAIT
  • और कुछ लेन-देन अलगाव स्तर कुछ भी पढ़ें के अलावा अन्य के लिए प्रतिबद्ध होना हो सकता है हो सकता है

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

[/ अतिरिक्त]

0

जेटीए लेनदेन का उपयोग करने के लिए एक संभावित कामकाज हो सकता है। यह आपके खुले/बंद जेडीबीसी कॉन्स पर "दृश्य के पीछे" कनेक्शन को खुला रखता है। हो सकता है कि यह आपके सर्वर को एक ही सर्वर पर रखे और इस सिंक की समस्या से बचें।

UserTransaction transaction = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction"); 
transaction.begin(); 
// doing multiple open/close cxs 
transaction.commit(); 
0

कोड स्निपेट में वास्तव में प्रतिबद्धता शामिल नहीं थी।

यदि आप प्रतिबद्ध करने के करीबी कनेक्शन पर निर्भर/भरोसा कर रहे हैं, तो यह सिंक्रोनस नहीं हो सकता है (यानी जब जावा कनेक्शन को बंद करने के लिए ओरेकल को बताता है तो कनेक्शन बंद हो सकता है, जिसका अर्थ है कि यह पहले हो सकता है प्रतिबद्ध ओरेकल द्वारा पूरा किया जाता है)।

+0

http : //java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html डिफ़ॉल्ट रूप से एक कनेक्शन ऑब्जेक्ट ऑटो-प्रतिबद्ध मोड में है, जिसका अर्थ है कि यह प्रत्येक को निष्पादित करने के बाद स्वचालित रूप से परिवर्तन करता है बयान। – Andrew

+0

यक। लेकिन यह भी लागू हो सकता है, क्योंकि इस पर कोई नियंत्रण नहीं है कि प्रतिबद्धता कब की जा रही है। इसके अलावा, अनावश्यक रूप से प्रदर्शन करने में प्रदर्शन प्रदर्शन (और संभवतः डेटा अखंडता के परिणाम) हैं। इसे बंद करें, स्पष्ट रूप से प्रतिबद्ध करें और देखें कि समस्या दूर हो गई है या नहीं। –

0

मुझे आपके कोड में कोई प्रतिबद्धता दिखाई नहीं देती है।वे इस तरह के ऐप में सबसे महत्वपूर्ण बयान हैं इसलिए मैं उन्हें हर बार स्पष्ट रूप से लिखा जाना चाहूंगा, न कि करीब() या इस तरह के निर्भर होने पर।

आपके पास अपने कनेक्शन (विज्ञापनों) पर डिफ़ॉल्ट रूप से ऑटोकॉमिट सेट भी हो सकता है जो वास्तव में व्यवहार की व्याख्या करेगा (यह प्रत्येक सम्मिलन/अद्यतन के बाद होता है)।

क्या आप जांच सकते हैं कि आपने वही किया है जहां आप उन्हें चाहते हैं, उदा। लेनदेन के अंत में और पहले नहीं?

यदि आप आंशिक रूप से आंशिक रूप से काम करते हैं, तो आपके पास अपने धागे के बीच दौड़ की स्थिति है जो यह भी समझाएगी कि भार बड़ा होने पर और अधिक समस्याएं क्यों हैं।

+0

मेरे पास ऑटो-प्रतिबद्धता सत्य पर सेट है हालांकि मुझे यकीन नहीं है कि यह उस व्यवहार को कैसे समझाएगा जो मैं देख रहा हूं। मैं एक सम्मिलित करता हूं और executeUpdate() जो स्वत: काम करता है, फिर बाद में एक चयन करने पर और उस डाली गई पंक्ति नहीं मिलती है। मैं नहीं देखता कि कैसे दौड़ की स्थिति यहां हो सकती है, इस पर विचार करते हुए कि executeUpdate() तब तक वापस नहीं आएगा जब तक यह प्रतिबद्ध नहीं हो जाता है। – Andrew

0

"भले ही सफलतापूर्वक पूरा होने से पहले सम्मिलित/अद्यतन प्रतिबद्धता चलती है।"

यह मुझे बताता है कि आप एक प्रतिबद्ध() जारी कर रहे हैं, और उसके बाद बाद में उसी डेटा को फिर से पढ़ने की उम्मीद है (यह दोहराया जा सकता है)।

यह मुझे बताता है कि आपको नहीं करना चाहिए। जब तक आप यह सुनिश्चित करना चाहते हैं कि कोई अन्य TASK उस डेटा में से किसी एक को संशोधित करने में सक्षम न हो जिसे आप स्पष्ट रूप से स्थिर रहने की उम्मीद करते हैं, तो आप ताले को जारी नहीं कर सकते हैं (जो प्रतिबद्ध है)।

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

शायद ओरेकल के स्नैपशॉट अलगाव के साथ क्या करने के लिए समस्याएं हैं जो मैं देख रहा हूं। अगर माफी माँगती है।

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