I'm experimenting a bit with google app engine and the lack of a transaction di framework is missing. I'm implementing it as good as I can, but I'm hitting the same exception again and again: can't operate on multiple entity groups in a single transaction. found both Element... I have read the documentation (http://code.google.com/appengine/docs/python/datastore/keysandentitygroups.h开发者_如何学编程tml#Entity_Groups_Ancestors_and_Paths) but I can't seem to get what they are implying. Basically what I'm trying to do is this:
I have a list of objects. I want to check if they are already in the database. If they are, i will check if they are equal, if not, update the managed instance. Otherwise I would persist the entity. In my loop of objects (not yet persisted objects), I use EntityMananger.find() to lookup the entity by Id. The second time around it gives an error.
I'm used of working with a spring/hibernate(JPA) or a EJB3 environment and I have not seen this before. Can anyone give me a simple explanation of why I can't do a find of 2 entities of the same type in the same transaction?
not searching for a how, but for a why...
Entity groups are a simple concept. Entities in App Engine have ancestors. For e.g. you could model Books and Authors.
Author: name->X, and Author: name->Y are two entities in the Author KIND. Book is another KIND (KIND is just a logical grouping of entities). The relationship between Books and Authors can be modeled as a ancestor-child relationship.
E.g.
Book: name->B1, B2 could have been written by Author: name->X. So you modeled them as:
Author: name->X is a parent of both Book: name->B1, B2. Similarly, Book: name->B3 is written by Author: name->Y and so could model that relationship as Author:name->Y is a parent of Book:name->B3.
When you try to transact on Books kind, you cannot transact on B1,B3 and B3 together. As they participate in different ancestor-child relationships. Every ancestor child relationship is an Entity group. You can only "lock" on one entity group at a time.
Hope this makes things a little clear.
From what I remember, the GAE datastore automatically groups your entities based on their hierarchy. For example, if you have a concept of a User, and you make all of your other object types (email messages, contacts, etc.) have User as a parent relationship, the GAE datastore considers all of those things to be part of the same group. If data related to a particular user seems to be getting pulled from a particular location a lot, Google can automatically move their data to a farm nearer that location to optimize data retrieval speeds.
The difficulty is that this means you have to either have all of your entities be tied to a main parent entity, or you have to avoid doing transactions across objects that are tied to different parent entities. Sometimes this isn't a big deal: moving a contact from one user account to another is not the sort of thing you'd expect to have happen as an atomic transaction in Gmail. Other times it can be a real drag.
精彩评论