2011-12-17 20 views
5

Hoy es la primera vez que uso GWT y JDO. Lo estoy ejecutando con Eclipse en el modo de depuración local.App-Engine La lectura consistente de JDO no funciona, ¿tal vez el almacenamiento en caché?

hago lo siguiente:

public Collection<MyObject> add(MyObject o) { 
PersistenceManager pm = PMF.get().getPersistenceManager(); 
try { 
    pm.makePersistent(o); 
    Query query = pm.newQuery(MyObject.class);// fetch all objects incl. o. But o only sometimes comes... 
List<MyObject> rs = (List<MyObject>) query.execute(); 
ArrayList<MyObject> list= new ArrayList<MyObject>(); 
for (MyObject r : rs) { 
    list.add(r); 
} 
return list; 
} finally { 
    pm.close(); 
} 
} 

ya puse en mi <property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />jdoconfig.xml. ¿Tengo que configurar algunas cosas de transacción en la configuración? ¿Alguien consiguió un trabajo jdoconfig.xml? ¿O es el problema en otro lugar? Algunos caché en medio?

EDIT: cosas que he intentado:

  • Configuración NontransactionalRead/escritura en false
  • Utilizando el PMF.get().getPersistenceManager() varias veces
  • el uso de transacciones mismo/a diferente PersistenceManager aunque llamando
  • ignoreCache = verdadero en PersistenceManager
  • llamando al flush y checkConsistency

El jdoconfig:

<persistence-manager-factory name="transactions-optional"> 
<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" /> 
    <property name="javax.jdo.PersistenceManagerFactoryClass" 
     value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/> 
    <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"/> 
</persistence-manager-factory> 

Debo estar perdiendo algo aquí porque el centro de todos los enfoques fallan ...

Edit2: Cuando Me dividir el trabajo en dos transacciones en el registro dice que la transacción de escritura pescó y luego comienza la transacción de lectura. Pero no encuentra el objeto simplemente persistente. Siempre dice Level 1 Cache of type "weak" initialised aswell. ¿La semana es mala o buena?

Alrededor del 30% de las solicitudes que salen mal ... ¿Puedo ser un problema de carga de consultas diferidas?

+1

También pesa sobre mí mismo problema. Agrego algunos objetos a través de mi aplicación, pero a veces no se reflejan en los resultados, ¡y a veces lo hacen! –

+0

y el objeto está en el almacén de datos en el momento de realizar la consulta? Obviamente, el registro te diría eso. Lo que esto tiene que ver con GWT no está claro ... – DataNucleus

+0

¿Dónde puedo encontrar un registro?¿Qué tiene que ver con GWT? Mucho, porque es un proyecto de GWT. Realmente no puedo trazar una línea clara entre GWT y el motor de la aplicación, por lo tanto, llamo a todo lo que GWT proviene de google. ¿Y por qué el almacenamiento en caché estaría tan desordenado que la misma instancia ni siquiera puede leer los datos recién escritos? ¿Podría publicar un jdoconfig.xml que siempre será coherente para el mismo cliente? –

Respuesta

2

Franz, la consistencia de lectura predeterminada en la configuración JDO es FUERTE. entonces si intenta acercarse en esa dirección, no lo llevará a ninguna parte

Compruébalo, ya que creo que menciona algo similar al escenario que está encontrando, con los datos confirmados no devueltos en la consulta. No es concurrente como se mencionó, pero explica el proceso de confirmación.

http://code.google.com/appengine/articles/transaction_isolation.html

Además, otra posibilidad sería realizar consultas mediante extensiones y averiguar si se soluciona el caso de uso particular que está viendo, ya que creo que se están retirando todos los registros en la tabla.

EDIT:

Dado que en el fragmento de código que usted ha mencionado, se consulta la tabla entera. Y si eso es lo que necesita, puede utilizar una Extensión ... La forma de usarlo es llamando

Extent ext = getExtent(<Entity Class name>)

en el objeto singleton PersistenceManager. Puede iterar a través de la extensión

Consulte la documentación y busque extensiones en la página aquí. http://code.google.com/appengine/docs/java/datastore/jdo/queries.html

+0

Está bien, dice que cuando se devuelve el compromiso no se garantiza que los cambios sean visibles (¿quién inventaría un concepto tan estúpido?). Ahora la pregunta es: ¿cómo puedo forzar la visibilidad? ¿O puedo hacer algunos trucos con mi cláusula where, porque dijiste algo sobre consultar toda la mesa? –

+1

Se actualizó el comentario sobre el uso de extensiones. Además, aquí hay una explicación del almacenamiento en caché en JDO. Puede ser de uso. http://book.javanb.com/using-and-understanding-java-data-objects/LiB0046.html – Hrishikesh

+0

Una extensión de una clase y una consulta de una clase son exactamente lo mismo FWIW – DataNucleus

2

Llamar al método makePersistent() no escribe en el almacén de datos; cerrar el PersistenceManager o confirmar sus cambios sí lo hace. Como no ha hecho esto cuando ejecuta su consulta, obtiene todos los objetos del almacén de datos que aún no incluye el objeto al que acaba de llamar makePersistent.

leer acerca de los estados de objetos aquí: http://db.apache.org/jdo/state_transition.html

Hay dos maneras de evitar esto, se puede poner esto dentro de una transacción ya que la escribe en el almacén de datos cometer (tener en cuenta GAE/entidad límite de tipo 5 de transacciones en las transacciones) y confirmar antes de ejecutar su consulta; Ejemplo utilizando la transacción ...

public Collection<MyObject> add(MyObject o) { 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    ArrayList<MyObject> list = null; 
    try { 
     Transaction tx=pm.currentTransaction(); 
     try { 
      tx.begin(); 
      pm.makePersistent(o); 
      tx.commit(); 
     } finally { 
      if (tx.isActive()) { 
       tx.rollback(); 
      } 
     } 

     Query query = pm.newQuery(MyObject.class); 
     List<MyObject> rs = (List<MyObject>) query.execute(); 
     ArrayList<MyObject> list = new ArrayList<MyObject>(); 
     for (MyObject r : rs) { 
      list.add(r); 
     } 
    } finally { 
     pm.close(); 
    } 

    return list; 
} 

o se puede cerrar el gestor de persistencia después de llamar makePersistent en O y luego abrir otra cuenta para ejecutar la consulta en.

// Note that this only works assuming the makePersistent call is successful 
public Collection<MyObject> add(MyObject o) { 
    PersistenceManager pm = PMF.get().getPersistenceManager(); 
    try { 
     pm.makePersistent(o); 
    } finally { 
     pm.close(); 
    } 

    pm = PMF.get().getPersistenceManager(); 
    ArrayList<MyObject> list = null; 
    try { 

     Query query = pm.newQuery(MyObject.class); 
     List<MyObject> rs = (List<MyObject>) query.execute(); 
     list= new ArrayList<MyObject>(); 
     for (MyObject r : rs) { 
      list.add(r); 
     } 

    } finally { 
     pm.close(); 
    } 

    return list; 
} 

NOTA: que originalmente dijo que sólo podría añadir o a la lista de resultados antes de regresar; pero eso no es algo inteligente, ya que hay un problema al escribir o en el almacén de datos; entonces la lista devuelta no reflejaría los datos reales en el almacén de datos.Hacer lo que ahora tengo (realizar una transacción o cerrar el pm y luego obtener otro) debería funcionar, ya que tiene su datastoreReadPolicy establecido en FUERTE.

+2

Intenté ambos enfoques y envolví leer y escribir en dos diferentes actas. Algunas veces funciona y otras no, esto está seriamente arruinado. Limpié el proyecto, degradado a jdk6 ahora que no tengo opciones. Incluso llamo a Flush y ConstancyCheck después de comprometerme, pero todo no ayuda. A veces, los datos simplemente no entran en el almacén de datos lo suficientemente rápido. Su idea anterior al agregar el nuevo objeto a los resultados manualmente. Lo hice, pero a veces recibo problemas una vez más, porque ese valor todavía no está en la tienda. Una actualización del navegador hace el truco entonces (¿en su mayoría?). –

+0

¿Está haciendo algún tipo de almacenamiento en caché? ya sea con algún tipo de mapa o a través de la API de Memcache? – Dave

1

Me encontré con el mismo problema y esto no ayudó. Dado que parece ser el resultado principal en Google por "la consistencia del motor de la aplicación jdo en eclipse" ¡pensé que compartiría la solución para mí!

Resulta que estaba usando instancias múltiples PersistenceManagerFactory que dio lugar a un comportamiento extraño. La solución es tener un singleton al que acceda cada fragmento de código. De hecho, este es documented correctly en los tutoriales de GAE, pero creo que su importancia está subestimada.

Conseguir un PersistenceManager Instancia

Una aplicación interactúa con JDO usando una instancia de la clase PersistenceManager . Obtiene esta instancia instanciando y llamando a un método en una instancia de la clase PersistenceManagerFactory. La fábrica usa la configuración de JDO para crear instancias de PersistenceManager.

Debido a que una instancia de PersistenceManagerFactory lleva tiempo inicializarse, una aplicación debe reutilizar una sola instancia. Una forma sencilla de gestionar el ejemplo PersistenceManagerFactory es crear un conjunto unitario clase contenedora con una instancia estática, de la siguiente manera:

PMF.java

import javax.jdo.JDOHelper; 
import javax.jdo.PersistenceManagerFactory; 

    public final class PMF { 
     private static final PersistenceManagerFactory pmfInstance = 
      JDOHelper.getPersistenceManagerFactory("transactions-optional"); 

     private PMF() {} 

     public static PersistenceManagerFactory get() { 
      return pmfInstance; 
     } 
    } 
+0

Si bien esto resuelve muchos otros problemas, esto no resolvió los problemas que enfrenta el póster original (también). La interfaz de administración de devserver tampoco refleja los cambios en los datos. Si dejo todo, simplemente me quedo sentado un rato, a veces, veré que las cosas persisten y estarán disponibles. Se siente aleatorio, aunque estoy seguro de que está pasando algo más. –

Cuestiones relacionadas