2009-07-09 13 views
19

Conozco todos los detalles sobre cómo funcionan los grupos de entidades en el almacenamiento de GAE, pero ayer (en la reunión de App Engine en Palo Alto), como presentador me explicaba su uso de grupos de entidades, me sorprendió que nunca lo usé realmente de ellos en mis propias aplicaciones GAE, y no recuerdo haberlos visto en aplicaciones GAE de código abierto que he usado.¿Buenos ejemplos de código abierto del uso de grupos de entidades en App Engine?

Entonces, sospecho que acabo de pasar por alto (sin notar o recordar) tales ejemplos porque simplemente no estoy acostumbrado a ellos para conectar de inmediato el "uso del grupo de entidades" al "tipo de problemas de aplicación que se resuelven" - y creo que debería remediarlo estudiando tales fuentes con este objetivo en mente, centrándome en qué problema está solucionando el uso de EG (es decir, por qué la aplicación funciona con él, pero no funcionaría o no funcionaría bien sin eso).

¿Alguien puede sugerir buenas URL para dicho código? (Los ensayos también serían bienvenidos, si se centran en la resolución de problemas a nivel de aplicación, pero no si, como la mayoría de los que he visto, simplemente se centran en los detalles de cómo funcionan los EGs! -).

Respuesta

22

El uso principal de los grupos de entidades es proporcionar los medios para actualizar más de una entidad en una transacción.

Si no las ha tenido que usar, cuente sus bendiciones. O ha estado diseñando sus modelos de datos de manera que no es necesario actualizar dos entidades al mismo tiempo para mantener la coherencia, o si los necesita pero ha tenido suerte :)

Imagínese que tengo un tipo de entidad de factura y un tipo de entidad LineItem. Una factura puede tener múltiples LineItems asociados a ella. La entidad My Factura tiene un campo llamado LastUpdated. Cada vez que se agrega un LineItem a mi factura, quiero almacenar la fecha actual en el campo LastUpdated.

Mi función de actualización podría tener este aspecto (pseudocódigo)

invoice.lastUpdated = now() 
lineitem = new lineitem() 

invoice.put() 
lineitem.put() 

¿Qué pasa si la opción de venta de facturas() tiene éxito y la opción de venta línea de pedido() falla? La fecha de mi factura mostrará que algo se actualizó, pero la actualización real (el nuevo LineItem) no estaría allí. La solución es poner ambas puts() dentro de una transacción.

Una solución alternativa sería utilizar una consulta para encontrar la fecha del último LineItem insertado, en lugar de almacenar estos datos en el campo lastUpdated. Pero eso implicaría obtener tanto la factura como todos los elementos de línea cada vez que quisiera saber la última vez que se agregó un elemento de línea, lo que le costará una cuota de almacenamiento de datos valiosa.

Editar para responder a los comentarios de la persona que

Ah. Creo que entiendo tu confusión. Los párrafos anteriores establecen por qué las transacciones son importantes. Pero dices que todavía no te importan los grupos de Entidades, porque no ves cómo se relacionan con las transacciones. Pero si usa db.run-in-transaction, entonces está usando grupos de entidades, ¡quizás sin darse cuenta! Cada transacción involucra a un solo grupo de entidades, y cualquier transacción determinada solo puede afectar a las entidades que pertenecen al mismo grupo. ver here

"Todas las operaciones del almacén de datos en una transacción deben operar en entidades en el mismo grupo de entidades".

¿Qué tipo de cosas estás haciendo en tus transacciones? Hay muchas buenas razones para usar transacciones con una sola Entidad, que por defecto está en su propio Grupo de Entidades.Pero a veces necesitas mantener sincronizadas 2 o más entidades, como en mi ejemplo anterior. Si la factura y las entidades de LineItem no están en el mismo grupo de entidades, entonces no podría envolver las modificaciones en una llamada db.run-in-transaction. Por lo tanto, cada vez que desee operar transaccionalmente en 2 o más entidades, primero debe asegurarse de que estén en el mismo grupo. Espero que sea más claro por qué son útiles.

+1

He usado db.run_in_transaction (ver http://code.google.com/appengine/docs/python/datastore/functions.html) para las transacciones (o por supuesto get_or_insert para ese caso especial, vea también http : //code.google.com/appengine/docs/python/datastore/transactions.html) - ¿Cuál es la ventaja de los grupos de entidades wrt? –

+1

¡ay! mi primer voto negativo. la ventaja de los grupos de entidades wrt para las transacciones es que las transacciones no funcionan fuera de los grupos de entidades. si ha estado usando transacciones, entonces ha estado usando grupos de entidades, aunque sea de manera implícita. cada entidad está en un grupo por defecto. las transacciones tienen un alcance limitado para afectar a un grupo de entidades a la vez. He editado mi respuesta con una explicación más larga. –

+0

¿Por qué está esto downvoted? Es una buena respuesta. –

2

Los he usado here. Estoy configurando el objeto de mi cliente como el padre de los marcadores del mapa. Esto crea un grupo de entidades para cada cliente y me da dos ventajas:

  1. Obtención de los marcadores de un cliente es mucho más rápido, porque están almacenados físicamente con el objeto de cliente (En el mismo servidor, probablemente. el mismo disco)

  2. Puedo cambiar los marcadores para un cliente en una transacción. Sospecho que el motivo por el cual las transacciones requieren que todos los objetos en los que operan estén en el mismo grupo es porque están almacenados en la misma ubicación física, lo que hace que sea más fácil implementar un bloqueo en los datos.

1

Los he usado here en este sencillo sistema wiki. La última versión de una página es siempre una entidad raíz y las versiones anteriores tienen la última versión como antecesor. La operación de copia se realiza en una transacción para mantener la consistencia de la versión y evitar perder una versión en caso de concurrencia.

Cuestiones relacionadas