Recuperación inconsistente del almacén de datos de Google App Engine
Tengo una aplicación implementada en el motor de aplicaciones de Google. Recibo datos inconsistentes cuando busco una entidad por id inmediatamente después de actualizar esa entidad. Estoy usando JDO 3.0 para acceder al almacén de datos del motor de la aplicación.
Tengo una entidad Empleado
@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() * */
}
Inicialmente, cuando creo un empleado, no establezco los campos salario y correo electrónico.
Actualizo la entidad Empleado para agregar salario y correo electrónico más tarde. La actualización funciona bien y los datos se conservan en el almacén de datos de appengine. Sin embargo, cuando trato de buscar la misma entidad de empleado por identificación, a veces obtengo los datos obsoletos, donde el salario y el correo electrónico son nulos. El código que uso para crear y buscar la entidad del empleado se proporciona a continuación.
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();
}
}
He establecido el número de instancias inactivas en 5 y hay alrededor de 8 instancias ejecutándose a la vez. Cuando revisé los registros de varias instancias, esto es lo que encontré.
¿Por qué obtengo datos obsoletos cuando la solicitud es atendida por ciertas instancias? Puedo asegurar que, si la solicitud de recuperación es manejada por la instancia que inicialmente manejó la solicitud de actualización, siempre obtengo los datos actualizados. Pero cuando otras instancias manejan la solicitud de recuperación, pueden devolverse datos obsoletos. He establecido explícitamente la consistencia de lectura del almacén de datos en fuerte en mi 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"/>
&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>