We have an entity defined as (id, name, school, & OTHER-FIELDS).
The id is auto assigned by datastore.
And we want to make sure the combination of <name, school> is unique in datastore.
Our code write like this:
/* First check uniqueness, then save */
public void savePerson(final Person newPerson) {
List<Person> existing = ofy().load().type(Person.clas)
.filter("name=", name)
.filter("school=", school)
.list();
if (existing == null || existing.isEmpty()) {
ofy.transact(new VoidWork() {
@Override
public void vrun() {
ofy.save.entity(newPerson).now();
}
}
}
}
But it still happens if multiple same savePerson calls happen at the same time (unpreventably we will face this), the duplicate check will fail (I think because when they start call savePerson() the data is not actually saved), and we find in AppEngine datastore it ended up with duplicate entities with the same <name, school> combinations.
We really want to make sure in our datastore given <name, school> we will end up with a unique entity
Can someone teach me how to add duplicate check atomically? Does it help if I move the existing entity check code into the transact context?
For example will the following code work?
/* Put filtering search into transaction too */
public void savePerson(final Person newPerson) {
ofy.transact(new VoidWork() {
@Override
public void vrun() {
List<Person> existing = ofy().load().type(Person.class)
.filter("name=", name)
.filter("school=", school)
.list();
if (existing == null || existing.isEmpty()) {
ofy.save.entity(newPerson).now();
}
}
}
}
Let me know if I should provide more details.