6

से असंगत प्राप्त करें मेरे पास Google ऐप इंजन में एक एप्लिकेशन तैनात है। जब मैं उस इकाई को अद्यतन करने के तुरंत बाद आईडी द्वारा एक इकाई प्राप्त करता हूं तो मुझे असंगत डेटा मिल रहा है। मैं ऐप इंजन डेटास्टोर तक पहुंचने के लिए जेडीओ 3.0 का उपयोग कर रहा हूं।Google App Engine डेटास्टोर

मैं शुरू में एक इकाई के कर्मचारी

@PersistenceCapable(detachable = "true") 
public class Employee implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -8319851654750418424L; 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY, defaultFetchGroup = "true") 
    @Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true") 
    private String id; 
    @Persistent(defaultFetchGroup = "true") 
    private String name; 
    @Persistent(defaultFetchGroup = "true") 
    private String designation;  
    @Persistent(defaultFetchGroup = "true") 
    private Date dateOfJoin;  
    @Persistent(defaultFetchGroup = "true") 
    private String email; 
    @Persistent(defaultFetchGroup = "true") 
    private Integer age; 
    @Persistent(defaultFetchGroup = "true") 
    private Double salary; 
    @Persistent(defaultFetchGroup = "true") 
    private HashMap<String, String> experience; 
    @Persistent(defaultFetchGroup = "true") 
    private List<Address> address; 


    /** 
     * Setters and getters, toString() * */ 

} 

है, जब मैं एक कर्मचारी बनाने मैं क्षेत्रों वेतन और ईमेल सेट न करें।

मैं बाद में वेतन और ईमेल जोड़ने के लिए कर्मचारी इकाई को अद्यतन करता हूं। अद्यतन ठीक काम करता है और डेटा एपेंगेन डेटास्टोर में जारी रहता है। हालांकि, जब मैं तुरंत आईडी द्वारा एक ही कर्मचारी इकाई लाने की कोशिश करता हूं, तो मुझे कभी-कभी पुराना डेटा मिलता है, जहां वेतन और ईमेल शून्य होते हैं। कोड इकाई को बनाने और लाने के लिए मैं जिस कोड का उपयोग करता हूं वह नीचे दिया गया है।

public Employee create(Employee object) { 
     Employee persObj = null; 
     PersistenceManager pm = PMF.get().getPersistenceManager(); 
     Transaction tx = null; 
     try { 
      tx = pm.currentTransaction(); 
      tx.begin(); 

      persObj = pm.makePersistent(object); 

      tx.commit(); 
     } finally { 

      if ((tx != null) && tx.isActive()) { 
       tx.rollback(); 
      } 

      pm.close(); 
     } 

     return persObj; 
    } 


    public Employee findById(Serializable id) { 

     PersistenceManager pm = PMF.get().getPersistenceManager(); 

     try { 
      Employee e = pm.getObjectById(Employee.class, id); 

      System.out.println("INSIDE EMPLOYEE DAO : " + e.toString()); 
      return e; 

     } finally { 

      pm.close(); 

     } 
    } 


    public void update(Employee object) { 
     PersistenceManager pm = PMF.get().getPersistenceManager(); 
     Transaction tx = null; 
     try { 
      tx = pm.currentTransaction(); 
      tx.begin(); 
      Employee e = pm.getObjectById(object.getClass(), object.getId()); 
      e.setName(object.getName()); 
      e.setDesignation(object.getDesignation()); 
      e.setDateOfJoin(object.getDateOfJoin()); 
      e.setEmail(object.getEmail()); 
      e.setAge(object.getAge()); 
     e.setSalary(object.getSalary()); 
      tx.commit(); 
     } finally { 
      if (tx != null && tx.isActive()) { 
       tx.rollback(); 
      } 

      pm.close(); 
     } 
    } 

मैं 5 से निष्क्रिय उदाहरणों की संख्या निर्धारित किया है और 8 एक समय में चल रही चारों ओर देखते हैं। जब मैंने विभिन्न उदाहरणों के लॉग की जांच की तो मुझे यही मिला। enter image description here

कुछ उदाहरणों से अनुरोध कब किया जाता है जब मुझे पुराना डेटा क्यों मिलता है। मैं यह आश्वस्त कर सकता हूं कि, अगर अनुरोध अनुरोध को प्रारंभिक रूप से अद्यतन अनुरोध को संभाला जाता है तो मुझे हमेशा अद्यतन डेटा मिलता है। लेकिन जब अन्य उदाहरण प्राप्त करने के अनुरोध को संभालते हैं तो पुराना डेटा वापस किया जा सकता है। मैंने अपने jdoconfig.xml में मजबूत करने के लिए डेटास्टोर पढ़ने की स्थिरता स्पष्ट रूप से सेट की है।

<?xml version="1.0" encoding="utf-8"?> 
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig_3_0.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig http://java.sun.com/xml/ns/jdo/jdoconfig_3_0.xsd"> 

    <persistence-manager-factory name="transactions-optional"> 
     <property name="javax.jdo.PersistenceManagerFactoryClass" 
      value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory"/> 
     <property name="javax.jdo.option.ConnectionURL" value="appengine"/> 
     <property name="javax.jdo.option.NontransactionalRead" value="true"/> 
     <property name="javax.jdo.option.NontransactionalWrite" value="true"/> 
     <property name="javax.jdo.option.RetainValues" value="true"/> 
     <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/> 
     <property name="datanucleus.appengine.singletonPMFForName" value="true"/> 
     <property name="datanucleus.appengine.datastoreEnableXGTransactions" value="true"/> 
     <property name="datanucleus.query.jdoql.allowAll" value="true"/>  
     <property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" /> 

    </persistence-manager-factory> 
</jdoconfig> 
+1

http://stackoverflow.com/search?q=%5Bgae%5D+eventual+consistency "अंतिम स्थिरता" में दिखता है जैसा कि ऐसा लगता है। –

+0

@ पॉलकॉलिंगवुड मैंने स्टैटोंग को डेटास्टोर पढ़ने की स्थिरता निर्धारित की है। HariShankar

+0

http://stackoverflow.com/questions/8112331/google-app-engine-jdo-makepersistent-latency – arundevma

उत्तर

2

मेरे पास एक सुझाव है, हालांकि आप इसे पसंद नहीं करेंगे: जीएई का उपयोग करते समय निम्न स्तर एपीआई का उपयोग करें और जेडीओ/जेपीए के बारे में भूल जाओ।

बस @asp ने कहा, आईडी द्वारा प्राप्त होना दृढ़ता से संगत होना चाहिए, हालांकि जीएई जेडीओ प्लगइन मुझे बग लगता है। दुर्भाग्यवश, जेपीए में माइग्रेट करने से मेरे मामले में कोई मदद नहीं मिली (यहां अधिक: JDO transactions + many GAE instances = overriding data)। इसके अलावा, अगर मैं @PersistenceAware के रूप में किसी भी वर्ग को एनोटेट करता हूं, ग्रहण पागल हो जाता है, और कक्षाओं को अनंत लूप में बढ़ाता है। साथ ही, एम्बेडेड क्लास और कैशिंग के साथ @PersistenceCapable क्लास का उपयोग करते समय मुझे बहुत सारी समस्याएं थीं (कैशिंग के बिना इसे ठीक काम किया)।

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

इसके अलावा, जीएई जेडीओ लिखते समय मुझे लगा ... अकेले। यदि आपको जावा, या यहां तक ​​कि एंड्रॉइड के साथ कोई समस्या है, तो हजारों लोगों को पहले से ही यह समस्या थी, इसके बारे में स्टैक ओवरफ्लो पर पूछा गया और कई ठोस समाधान मिल गए। यहां आप सभी अपने आप हैं, इसलिए जितना संभव हो उतना निम्न स्तर एपीआई के रूप में उपयोग करें और आप सुनिश्चित होंगे कि क्या हो रहा है। हालांकि माइग्रेशन नरक और समय लेने वाली के रूप में डरावना लगता है, मुझे लगता है कि आप जीएई जेडीओ/जेपीए से निपटने के बजाय निम्न स्तर एपीआई में माइग्रेट करने में कम समय बर्बाद कर देंगे। मैं जीएई जेडीओ/जेपीए विकसित करने वाली टीम को चुटकी देने या उन्हें अपमानित करने के लिए नहीं लिखता, मुझे यकीन है कि वे अपनी पूरी कोशिश करते हैं। लेकिन:

  1. बहुत सारे लोग हैं नहीं की तुलना GAE का उपयोग कर, का कहना है की सुविधा देता है, Android या सामान्य

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

  3. Google पाइथन जीएई पर जावा से कहीं अधिक केंद्रित है। कई ऑडियंस के लिए लक्षित कई लेखों में, पाइथन कोड और विशेष रूप से संकेत हैं, यहां त्वरित उदाहरण: http://googlecloudplatform.blogspot.com/2013/12/best-practices-for-app-engine-memcache.html या यहां: https://cloud.google.com/developers/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/। मैंने देखा है कि विकास शुरू करने से पहले भी, लेकिन मैं अपने एंड्रॉइड क्लाइंट के साथ कुछ कोड साझा करना चाहता था, इसलिए मैंने जावा चुना। भले ही मेरे पास ठोस जावा पृष्ठभूमि है और यहां तक ​​कि मैं अब कुछ कोड साझा करता हूं, अगर मैं समय पर वापस जा सकता हूं और फिर से चुन सकता हूं, तो अब मैं पाइथन चुनूंगा।

Thats मुझे डेटा का उपयोग और कुशलतापूर्वक उपयोग करने के लिए केवल सबसे बुनियादी तरीकों का उपयोग करने के लिए सबसे अच्छा क्यों लगता है।

शुभकामनाएं, मैं आपको शुभकामनाएं देता हूं।

+0

मैंने निम्न स्तर एपीआई का उपयोग करके संचालन लाने की कोशिश की। यह बढ़िया काम करता है। शेष परिचालन अभी भी जेडीओ का उपयोग करते हैं। सुनिश्चित नहीं है कि इससे और समस्याएं पैदा होंगी। – HariShankar

4

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

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

https://cloud.google.com/appengine/docs/java/datastore/queries#Java_Data_consistency https://cloud.google.com/appengine/docs/java/datastore/jdo/overview-dn2#Setting_the_Datastore_Read_Policy_and_Call_Deadline

कृपया दस्तावेज के बारे में Structuring Data for Strong Consistency पर एक नजर है, वरीय दृष्टिकोण कैशिंग परत डेटा दिखाने के लिए है।

मैंने देखा है कि आप आईडी द्वारा प्राप्त कर रहे हैं, यकीन नहीं है, लेकिन "कुंजी से प्राप्त करें" एचआर डेटास्टोर (reference) के लिए भी दृढ़ता से संगत होना चाहिए, क्या आप इसे कुंजी के आधार पर क्वेरी में बदलने का प्रयास कर सकते हैं? कुंजी आईडी और इकाई प्रकार और वंश का उपयोग करके बनाई गई है।