2012-11-27 7 views
28

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

ठीक है, इसलिए इसकी उम्मीद भी की जा सकती है, इसलिए जब ब्राउज़र विफल हो जाता है तो शायद ब्राउज़र फिर से लिखने का प्रयास करता है (शायद सबसे अच्छा हैक नहीं है लेकिन मैं इसे जल्दी से काम करने की कोशिश कर रहा हूं)।

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

कोड निम्नानुसार है। कुछ चीजें ध्यान दें:

  1. मैं automatic JDO caching का उपयोग करने का प्रयास कर रहा हूं। तो यह वह जगह है जहां जेडीओ कवर के तहत memcache का उपयोग करता है। यह वास्तव में तब तक काम नहीं करता जब तक आप लेनदेन में सबकुछ लपेट नहीं लेते।
  2. सभी अनुरोध एक इकाई से एक स्ट्रिंग पढ़ रहे हैं, स्ट्रिंग के हिस्से को संशोधित कर रहे हैं, और उस स्ट्रिंग को इकाई में वापस सहेज रहे हैं। यदि ये अनुरोध लेनदेन में नहीं थे, तो निश्चित रूप से आपको "गंदे पढ़ने" की समस्या होगी। लेकिन लेनदेन के साथ, अलगाव "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); 
    
    :
  3. इकाई संशोधित किया जा रहा एक रूट इकाई (एक समूह में नहीं)
  4. मैं पार समूह लेनदेन को सक्षम किया

प्रासंगिक कोड (इस एक सरलीकृत संस्करण है) है

अद्यतन: मैं यकीन है कि मैं जानता हूँ कि क्यों यह हो रहा है, लेकिन मैं अभी भी किसी को इनाम जो इसे पुष्टि कर सकते हैं अवार्ड होगा।

असल में, मुझे लगता है कि समस्या यह है कि लेनदेन वास्तव में डेटास्टोर के स्थानीय संस्करण में लागू नहीं किए जाते हैं। संदर्भ:

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

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

+0

क्या आपने एक ही इकाई समूह में प्रति सेकंड एक से अधिक बार रहने से बचने के लिए अपने डेटास्टोर को फिर से डिजाइन करने और इसका उपयोग करने के बारे में सोचा है? वैकल्पिक रूप से, क्या आपने डेटास्टोर को कार्यरत कार्यों तक पहुंचने और 1/एस इकाई समूह लिखने की आवृत्ति सीमा का सम्मान करने के लिए चीजों की व्यवस्था करने की कोशिश की है? –

+0

मैंने इसके बारे में सोचा है। लेकिन इससे पहले कि, मैं समझना चाहता हूं कि यह विशेष बग क्यों हो रहा है ... मेरी चिंता यह है कि मैं मूल रूप से एचआरडी या ऐप इंजन/जेडीओ लेनदेन या कुछ के बारे में कुछ नहीं समझता, या मुझे कुछ याद आया प्रलेखन, और यह मुझे बाद में काटने जा रहा है, क्योंकि मेरे पास कम से कम 25 अन्य सेवाएं हैं जिन्हें मुझे लेनदेन जोड़ने की आवश्यकता है (यदि डेटास्टोर एक्सेस लेनदेन में नहीं हैं तो जेडीओ कैशिंग काम नहीं करेगा) – eeeeaaii

+0

एफडब्ल्यूआईडब्ल्यू, वर्तमान प्लगइन का उपयोग कर (जीएई जेडीओ v2.x), मुझे काम करने के लिए एल 2 कैश के लेनदेन में पहुंच के लिए कोई आवश्यकता नहीं है; यदि कोई ऑब्जेक्ट पढ़ा जाता है तो यह एल 2 कैश किया जाता है और यदि ऐसा नहीं होता है तो इसकी सूचना दी जानी चाहिए (जाहिर है पुरानी प्लगइन समर्थित नहीं है, इसलिए वर्तमान में ऐसी चीज की रिपोर्ट करें)। – DataNucleus

उत्तर

1

आप के लिए हो सकता है कि बुरी खबर है, मैं JDO छोड़ दिया और मैं objectify उपयोग कर रहा हूँ और कुछ स्थानों पर सीधे datanucleus।मेरे दृढ़ता पर मेरा पूर्ण नियंत्रण है जो एक प्रदर्शन और डिजाइन बेहतर विकल्प है (यदि आप लंबी अवधि में सोचते हैं)।

देशी datanucleus एपीआई आप चीजें हैं जो मानक जेपीए में है और न ही यहां तक ​​कि objectify में नहीं हैं क्या कर सकते हैं का उपयोग करना::

क्योंकि db कोई एसक्यूएल है, वहाँ जेपीए, JDO और मानक मान्यताओं के खिलाफ संरचनात्मक परिवर्तन कर रहे हैं उदाहरण मैं कॉलम गतिशील रूप से

लेनदेन जीएई में मौजूद नहीं है, ऐसा कुछ ऐसा है जो कभी-कभी लेनदेन (इकाई समूह) जैसा दिखता है। तो देशी एपीआई का उपयोग करने से आप इस तरह के अव्यवस्थित जिमनास्टिक से बचेंगे।

जॉयस्टिक के साथ एक कार चलाने की कोशिश कर काम कर सकता है, लेकिन निश्चित रूप से सीखने के लिए नई चीजें हैं। मेरी राय में मूल तरीका सीखने के लायक है

+1

ज़ेड सही है। हालांकि यह हल्का दिलचस्प है कि Google जेपीए और जेडीओ अमूर्त परत प्रदान करता है, मैंने कभी ऐसा प्रोजेक्ट नहीं देखा है जो उनके साथ बहुत अच्छी तरह से चला गया हो। यह आमतौर पर सभी प्रकार के ग़लत हैक में समाप्त होता है क्योंकि इस तथ्य के चलते लोग आरडीबीएमएस के रूप में बैकिंग डेटास्टोर के बारे में सोचते रहते हैं, जब यह निश्चित रूप से नहीं होता है। मैं दृढ़ता से सुझाव देता हूं कि लोग जेपीए या जेडीओ पुस्तकालयों का उपयोग न करें और कच्चे Google एपीआई या ऑब्जेक्टिफा का उपयोग करें। –

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