Providing Unique Constraints in GAE

I'm trying to use Google App Engine Java, however, the lack of a unique restriction makes it difficult. I have been through this post and this blog offers a method for implementing something like this, My experience in MySQL. Going to the data warehouse without a unique restriction makes me nervous because I never had to worry about duplicate values ​​and check each value before inserting a new value, there is still room for error.

"No, you still cannot specify unique when creating the schema."

- David Underhill talks about GAE and the unique constraint ( post link )

What do you guys use to implement something that looks like a unique or primary key?

I heard about an abstract repository layer created using a low-level api that worked like a regular RDB, which, however, was not free (but I don’t remember the name of the software)

Schematic illustration of my problem

sNo = biggest serial_number in the db sNo++ Insert new entry with sNo as serial_number value //checkpoint User adds data pertaining to current serial_number Update entry with data where serial_number is sNo 

However, on line number 3 (breakpoint), I feel that two users can add the same sNo. And that prevents me from working with appengine.

+6
google-app-engine unique datastore
source share
4 answers

You can create unique serial numbers for your products without having to use unique identifiers or query the entire set of objects to find out which is the largest serial number currently. You can use transactions and a singleton object to generate the "next" serial number. Since the operation takes place inside the transaction, you can be sure that neither of the two products will ever receive the same serial number.

This approach, however, will be a potential performance chance and limit the scalability of the application. If it’s so that creating new serial numbers doesn’t happen so often that you get frustrated, this might work for you.

EDIT: To clarify, a singleton that contains the current or next serial number to be assigned is completely independent of any objects that actually have serial numbers assigned to them. They do not have to be part of a group of entities. You can have objects from several models using the same mechanism to get a new unique serial number.

I don’t remember Java very well to provide sample code, and my Python example may not make sense to you, but here is pseudocode to illustrate the idea:

  • Get a request to create a new inventory item.
  • Enter a transaction.
  • Get the current value of a single SerialNumber model object.
  • Increase value and write it to the database
  • The return value when exiting a transaction.

Now, the code that does all the work of creating an inventory item and storing it along with its new serial number does NOT need to be run in a transaction.

Caution: as I said above, this can be a major performance bottleneck, since only one serial number can be created at any one time. However, it gives you the assurance that the serial number you just created is unique and not in use.

+4
source share

This and other similar questions often arise when it comes to moving from a traditional RDB to a data warehouse like BigTable, such as App Engine.

It is often useful to discuss why the data warehouse does not support unique keys, as it informs the thinking you should be in when you think about your data storage schemes. The reason unique constraints are not available is because it significantly limits scalability. As you said, enforcing a constraint means checking all other objects for this property. Regardless of whether you do this manually in your code, or whether the data warehouse is automatically behind the scenes, this should happen anyway, which means lower performance. Some optimizations can be made, but it should still happen anyway.

The answer to your question: really think about why you need this unique limitation.

Secondly, remember that keys exist in the data store and are a great way to provide a simple unique constraint.

 my_user = MyUser(key_name=users.get_current_user().email()) my_user.put() 

This ensures that MyUser will never be created with this email, and you can also quickly get MyUser with this email address:

 my_user = MyUser.get(users.get_current_user().email()) 

In the python runtime, you can also:

 my_user = MyUser.get_or_create(key_name=users.get_current_user().email()) 

What will insert or retrieve the user with this email.

Anything more complicated will not be scalable. So really think about whether you need this property to be globally unique, or if there are ways to eliminate the need for this unique restriction. Often you will find with some small workarounds that you do not need so that the property is unique in the end.

+12
source share

I encountered the same problem in an application where users need to reserve a time interval. I needed to β€œinsert” exactly one unique unit of time, expecting users to simultaneously request the same time interval.

I highlighted an example of how to do this in the application, and I wrote about it on the blog . The blog has examples of canonical codes using Datastore, as well as Objectify. (By the way, I would advise avoiding JDO.)

I also launched a live demo where you can promote two users to reserve the same resource. In this demo, you can find out the exact behavior of the application data store for click-throughs.

If you are looking for unique constraint behavior, this should be helpful.

-broc

+3
source share

At first, I thought that an alternative to the transaction method on the broc blog could be to create a singleton class that contains a synchronized method (like addUserName (String name)), responsible for adding a new record, only if it is unique or throws an exception, Then create a contextlistener. which will instantiate one instance of this singleton by adding it as an attribute to servletContext. Servlets can then call the addUserName () method on the singleton instance that they get through getServletContext.

However, this is NOT a good idea because GAE can split an application into multiple JVMs, so multiple instances of the same single class can occur, one in each JVM. see this topic

Another GAE alternative is to write the GAE module, which is responsible for checking the uniqueness and adding new entems; then use manual or basic scaling with ...

 <max-instances>1</max-instances> 

Then you have one instance running in GAE that acts as a single authority point, adding users one at a time to the data warehouse. If you are concerned that this instance is a bottleneck, you can improve the module, add priority or internal master / slave architecture.

This module-based solution would add many unique user names to the data warehouse in a short period of time without risking group competition problems.

0
source share

All Articles