Inkonsistenter Abruf aus dem Google App Engine-Datenspeicher

Ich habe eine Anwendung in Google App Engine bereitgestellt. Ich erhalte inkonsistente Daten, wenn ich eine Entität nach ID unmittelbar nach der Aktualisierung dieser Entität abrufe. Ich verwende JDO 3.0, um auf den App Engine-Datenspeicher zuzugreifen.

Ich habe ein Unternehmen Mitarbeiter

@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() * */

}

Wenn ich einen Mitarbeiter erstelle, werden die Felder Gehalt und E-Mail nicht festgelegt.

Ich aktualisiere die Entität Employee, um später Gehalt und E-Mail hinzuzufügen. Das Update funktioniert einwandfrei und die Daten bleiben im Appengine-Datenspeicher erhalten. Wenn ich jedoch sofort versuche, dieselbe Mitarbeiterentität anhand der ID abzurufen, erhalte ich manchmal die veralteten Daten, bei denen Gehalt und E-Mail-Adresse null sind. Der Code, den ich zum Erstellen und Abrufen der Entität "employee" verwende, ist unten angegeben.

    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();
        }
    }

Ich habe die Anzahl der inaktiven Instanzen auf 5 festgelegt und es werden ungefähr 8 Instanzen gleichzeitig ausgeführt. Als ich die Protokolle verschiedener Instanzen überprüfte, fand ich Folgendes.

Warum erhalte ich veraltete Daten, wenn die Anforderung von bestimmten Instanzen bedient wird. Ich kann versichern, dass ich immer die aktualisierten Daten erhalte, wenn die Abrufanforderung von der Instanz verarbeitet wird, die ursprünglich die Aktualisierungsanforderung verarbeitet hat. Wenn jedoch andere Instanzen die Abrufanforderung verarbeiten, werden möglicherweise veraltete Daten zurückgegeben. Ich habe die Lesekonsistenz des Datenspeichers in meiner jdoconfig.xml explizit auf strong gesetzt.

<?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"/>
       &l,t;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>

Antworten auf die Frage(3)

Ihre Antwort auf die Frage