I have an application deployed to a Google application. I get inconsistent data when I get an object by ID immediately after updating this object. I am using JDO 3.0 to access the application data store.
I have an Employee employee
@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; }
Initially, when I create an employee, I do not set salary fields and email.
I am updating the Employee object to add salary and email later. The update works fine, and the data is saved in the application store. However, when I immediately try to get the same employee object by id, I sometimes get outdated data, where salary and email are zero. The code I use to create and retrieve the employee object is shown below.
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(); } }
I set the number of unoccupied instances to 5, and about 8 instances will be launched at the same time. When I checked the logs of different instances, this is what I found. 
Why do I get stale data when a request is served by specific instances. I can assure that if the selection request is processed by the instance that originally processed the update request, I always get updated data. But when other instances process the fetch request, stale data may be returned. I have clearly established the consistency of reading the data store in my 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>