Google app engine 如何使用Objectify for AppEngine应用拒绝并发重复保存

Google app engine 如何使用Objectify for AppEngine应用拒绝并发重复保存,google-app-engine,objectify,Google App Engine,Objectify,我们有一个实体定义为(id、name、school和OTHER-FIELDS)。 id由数据存储自动分配。 我们希望确保的组合在数据存储中是唯一的 我们的代码是这样写的: /* First check uniqueness, then save */ public void savePerson(final Person newPerson) { List<Person> existing = ofy().load().type(Person.clas)

我们有一个实体定义为
(id、name、school和OTHER-FIELDS)
id
由数据存储自动分配。 我们希望确保
的组合在数据存储中是唯一的

我们的代码是这样写的:

/* 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();
            }
        }
    }
}

让我知道我是否应该提供更多详细信息。

要想做你想做的事,必须使用一个事务来读取是否已经有给定的名称+学校并保存实体;否则,如果您有多个并发用户,那么您将不再拥有重复的用户。您可以只加载第一个实体[即first()],而不是加载整个列表。确保“名称”和“学校”已编入索引(即@Index)。还要检查web.xml中是否有ObjectifyFilter


但是请注意,同一所学校可能有两个同名的不同人员,因此您应该添加另一种区分人员的方法。

这需要对数据库设计进行一些重新构造,但是否可以接受应用程序级别的唯一标识符?这将比一个人类的唯一性范围的更高开销表现得更好。看见
/* 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();
            }
        }
    }
}