मैं ऐप इंजन पर जेडीओ 2.3 का उपयोग कर रहा हूं। मैं स्थानीय परीक्षण के लिए मास्टर/स्लेव डेटास्टोर का उपयोग कर रहा था और हाल ही में स्थानीय परीक्षण के लिए एचआरडी डेटास्टोर का उपयोग करने के लिए स्विच किया गया था, और मेरे ऐप के कुछ हिस्सों को तोड़ रहा है (जिसे उम्मीद की जा सकती है)। ऐप का एक हिस्सा जो टूट रहा है वह है जहां यह बहुत सारे लिखने को जल्दी भेजता है - यह 1-सेकंड की सीमा की वजह से है, यह एक समवर्ती संशोधन अपवाद के साथ विफल रहा है।प्रतिबद्ध जेडीओ लिखते हैं स्थानीय जीएई एचआरडी पर लागू नहीं होते हैं, या संभावित रूप से लेनदेन
ठीक है, इसलिए इसकी उम्मीद भी की जा सकती है, इसलिए जब ब्राउज़र विफल हो जाता है तो शायद ब्राउज़र फिर से लिखने का प्रयास करता है (शायद सबसे अच्छा हैक नहीं है लेकिन मैं इसे जल्दी से काम करने की कोशिश कर रहा हूं)।
लेकिन एक अजीब बात हो रही है। कुछ लिखने वाले जो सफल होना चाहिए (वे जो समवर्ती संशोधन अपवाद नहीं प्राप्त करते हैं) भी विफल हो रहे हैं, भले ही प्रतिबद्ध चरण पूरा हो और अनुरोध मेरा सफलता कोड लौटाए। मैं लॉग से देख सकता हूं कि पुनः प्रयास किए गए अनुरोध ठीक से काम कर रहे हैं, लेकिन ये अन्य अनुरोध जो पहले प्रयास पर किए गए प्रतीत होते हैं, मुझे लगता है, कभी भी "लागू नहीं" होता है। लेकिन जो मैंने लागू चरण के बारे में पढ़ा है, उसी इकाई को फिर से लिखना लागू करना चाहिए ... लेकिन ऐसा नहीं है।
कोड निम्नानुसार है। कुछ चीजें ध्यान दें:
- मैं automatic JDO caching का उपयोग करने का प्रयास कर रहा हूं। तो यह वह जगह है जहां जेडीओ कवर के तहत memcache का उपयोग करता है। यह वास्तव में तब तक काम नहीं करता जब तक आप लेनदेन में सबकुछ लपेट नहीं लेते।
- सभी अनुरोध एक इकाई से एक स्ट्रिंग पढ़ रहे हैं, स्ट्रिंग के हिस्से को संशोधित कर रहे हैं, और उस स्ट्रिंग को इकाई में वापस सहेज रहे हैं। यदि ये अनुरोध लेनदेन में नहीं थे, तो निश्चित रूप से आपको "गंदे पढ़ने" की समस्या होगी। लेकिन लेनदेन के साथ, अलगाव "serializable" के स्तर पर होना चाहिए, इसलिए मुझे नहीं पता कि यहां क्या हो रहा है।
:PersistenceManager pm = PMF.getManager(); Transaction tx = pm.currentTransaction(); String responsetext = ""; try { tx.begin(); // I have extra calls to "makePersistent" because I found that relying // on pm.close didn't always write the objects to cache, maybe that // was only a DataNucleus 1.x issue though Key userkey = obtainUserKeyFromCookie(); User u = pm.getObjectById(User.class, userkey); pm.makePersistent(u); // to make sure it gets cached for next time Key mapkey = obtainMapKeyFromQueryString(); // this is NOT a java.util.Map, just FYI Map currentmap = pm.getObjectById(Map.class, mapkey); Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity Text newMapData = parseModifyAndReturn(mapData); // transform the map currentmap.setMapData(newMapData); // mutate the Map object pm.makePersistent(currentmap); // make sure to persist so there is a cache hit tx.commit(); responsetext = "OK"; } catch (JDOCanRetryException jdoe) { // log jdoe responsetext = "RETRY"; } catch (Exception e) { // log e responsetext = "ERROR"; } finally { if (tx.isActive()) { tx.rollback(); } pm.close(); } resp.getWriter().println(responsetext);
- इकाई संशोधित किया जा रहा एक रूट इकाई (एक समूह में नहीं)
- मैं पार समूह लेनदेन को सक्षम किया
प्रासंगिक कोड (इस एक सरलीकृत संस्करण है) है
अद्यतन: मैं यकीन है कि मैं जानता हूँ कि क्यों यह हो रहा है, लेकिन मैं अभी भी किसी को इनाम जो इसे पुष्टि कर सकते हैं अवार्ड होगा।
असल में, मुझे लगता है कि समस्या यह है कि लेनदेन वास्तव में डेटास्टोर के स्थानीय संस्करण में लागू नहीं किए जाते हैं। संदर्भ:
https://groups.google.com/forum/?fromgroups=#!topic/google-appengine-java/gVMS1dFSpcU https://groups.google.com/forum/?fromgroups=#!topic/google-appengine-java/deGasFdIO-M https://groups.google.com/forum/?hl=en&fromgroups=#!msg/google-appengine-java/4YuNb6TVD6I/gSttMmHYwo0J
क्योंकि लेनदेन से लागू नहीं कर रहे हैं, रोलबैक अनिवार्य रूप से एक नहीं सेशन है। इसलिए, जब मैं दो लेनदेन एक ही समय में रिकॉर्ड को संशोधित करने का प्रयास करता हूं तो मुझे गंदा पढ़ा जाता है। दूसरे शब्दों में, ए डेटा पढ़ता है और बी एक ही समय में डेटा पढ़ता है। डेटा को संशोधित करने का प्रयास, और बी डेटा के एक अलग हिस्से को संशोधित करने का प्रयास करता है। एक डेटास्टोर को लिखता है, फिर बी लिखता है, ए के परिवर्तन को खत्म कर देता है। फिर बी 'वापस लुढ़का "है एप्लिकेशन इंजन द्वारा, लेकिन जब से पुनरावर्तन नो-सेशन हैं जब स्थानीय डेटासंग्रह पर चल रहा है, बी के परिवर्तन रहने के लिए, और एक के नहीं है। इस बीच, के बाद से बी धागा है कि अपवाद फेंक दिया है, ग्राहक बी पुनः प्रयास करता है, लेकिन एक पुन: प्रयास नहीं करता है (के बाद से एक माना जाता है कि लेन-देन है कि सफल रहा था)।
क्या आपने एक ही इकाई समूह में प्रति सेकंड एक से अधिक बार रहने से बचने के लिए अपने डेटास्टोर को फिर से डिजाइन करने और इसका उपयोग करने के बारे में सोचा है? वैकल्पिक रूप से, क्या आपने डेटास्टोर को कार्यरत कार्यों तक पहुंचने और 1/एस इकाई समूह लिखने की आवृत्ति सीमा का सम्मान करने के लिए चीजों की व्यवस्था करने की कोशिश की है? –
मैंने इसके बारे में सोचा है। लेकिन इससे पहले कि, मैं समझना चाहता हूं कि यह विशेष बग क्यों हो रहा है ... मेरी चिंता यह है कि मैं मूल रूप से एचआरडी या ऐप इंजन/जेडीओ लेनदेन या कुछ के बारे में कुछ नहीं समझता, या मुझे कुछ याद आया प्रलेखन, और यह मुझे बाद में काटने जा रहा है, क्योंकि मेरे पास कम से कम 25 अन्य सेवाएं हैं जिन्हें मुझे लेनदेन जोड़ने की आवश्यकता है (यदि डेटास्टोर एक्सेस लेनदेन में नहीं हैं तो जेडीओ कैशिंग काम नहीं करेगा) – eeeeaaii
एफडब्ल्यूआईडब्ल्यू, वर्तमान प्लगइन का उपयोग कर (जीएई जेडीओ v2.x), मुझे काम करने के लिए एल 2 कैश के लेनदेन में पहुंच के लिए कोई आवश्यकता नहीं है; यदि कोई ऑब्जेक्ट पढ़ा जाता है तो यह एल 2 कैश किया जाता है और यदि ऐसा नहीं होता है तो इसकी सूचना दी जानी चाहिए (जाहिर है पुरानी प्लगइन समर्थित नहीं है, इसलिए वर्तमान में ऐसी चीज की रिपोर्ट करें)। – DataNucleus