COMP 405
|
Data Storage in GAE |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
There are three basic ways to store data in GAE:
Consistency issues with distributed DBs....
Here, the data storage is much like a giant, distributed key-value dictionary. The value contains multiple pieces of data all related to the same key. .
What corresponds to a traditional key-value pair is called an Entity.
The key of an Entity has 3 parts:
There are several ways to access data from Java:
An esier approach that the above 3 techniques is to use Objectify, a package makes it easier to use the datastore. Objectify is not an industry standard like JDO or JPA but it is geared towards getting novices up and running faster.
- url: /* filter: com.googlecode.objectify.ObjectifyFilter name: ObjectifyFilter
It is very common to desire that a new Entity to be stored in the DB is unique in the DB, e.g. a new user in a system. In a typical RDBS, one does this by specifying that a key is unique. But GAE's Datastore doesn't quite work that way.
GAE Datastore has two important "features" to be aware of:
To test if something is in the DB, one essentially must try to read it and then react if the requested Entity does not yet exist.
Since the process of making sure an Entity is unique involves multiple DB interactions, the use of "transactions" is in order. A transaction is a unit of work on a DB that insures that the operations in that work form an atomic process on the DB.
In pseudo-code:
Example: (IResult is an abstract result type used for processing success, fail, etc. processing results)
try { return ofy().transact(new Work<IResult>(){ // Start a transaction @Override public IResult run() { User newUser = new User(name, groups); // Make the desired Entity if (null == ofy().load().entity(newUser).getValue()) { // Try to read the Entity from the DB ofy().save().entity(newUser); // Nothing found, so safe to save return new SuccessResult("Successfully created new user "+name); } else { // Entity with same Id found in DB, so error. return new FailResult("User "+name+" already exists!"); } } }); } catch(Exception e){ // Exception will be thrown if concurrent modification occurs. return new FailResult("Exception: "+e.getMessage()); }
References:
© 2015 by Stephen Wong