java - 如何在交易中创建具有独特属性的实体?

标签 java google-app-engine google-cloud-datastore objectify

我正在使用对象化。比如说,我有一个 User 类型,它具有 nameemail 属性。实现注册时,我想检查是否已注册具有相同名称 相同电子邮件的用户。因为可以从许多来源调用注册,所以可能会出现竞争条件。

为了防止竞争条件,一切都必须以某种方式包装在事务中。如何消除竞争条件?

GAE 文档解释了如何在实体不存在的情况下创建实体,但它们假设 ID 已知。因为,我需要检查两个无法指定 ID 的属性。

最佳答案

受@konqi 回答的启发,我想出了一个类似的解决方案。

想法是创建User_NameUser_Email将保留迄今为止创建的所有用户的姓名和电子邮件的实体。不会有父子关系。为了方便起见,我们也将保留用户的姓名和电子邮件属性;我们正在用存储换取更少的读/写。

@Entity
public class User {
    @Id public Long id;

    @Index public String name;
    @Index public String email;
    // other properties...
}
@Entity
public class User_Name {
    private User_Name() {
    }

    public User_Name(String name) {
        this.name = name;
    }

    @Id public String name;
}
@Entity
public class User_Email {
    private User_Email() {
    }

    public User_Email(String email) {
        this.email = email;
    }

    @Id public String email;
}

现在通过检查唯一字段在交易中创建用户:

User user = ofy().transact(new Work<User>() {
    @Override
    public User run()
    {
        User_Name name = ofy().load().key(Key.create(User_Name.class, data.username)).now();
        if (name != null)
            return null;

        User_Email email = ofy().load().key(Key.create(User_Email.class, data.email)).now();
        if (email != null)
            return null;

        name = new User_Name(data.username);
        email = new User_Email(data.email);

        ofy().save().entity(name).now();
        ofy().save().entity(email).now();

        // only if email and name is unique create the user

        User user = new User();
        user.name = data.username;
        user.email = data.email;
        // fill other properties...

        ofy().save().entity(user).now();

        return user;
    }
});

这将保证这些属性的唯一性(至少我的测试凭经验证明了这一点 :))。并且不使用 Ref<?> s 我们保持数据紧凑,这将减少查询。

如果只有一个独特的属性,最好将其设为 @Id主体。

也可以设置 @Id用户的电子邮件或姓名,并将新种类的数量减少一个。但我认为为每个独特的属性创建一个新的实体类型会使意图(和代码)更加清晰。

关于java - 如何在交易中创建具有独特属性的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33290013/

相关文章:

java - 我们如何为 TextView 中的所有单词设置可点击?

java - 其中查询在 Grails 中无法正常工作

java - 如何使用 JAXB 驱动程序获取 xml 标签名称

java - 如何从 Scala 应用程序使用 Google App Engine 数据存储区?

eclipse - java.lang.ClassNotFoundException : com. sun.jersey.spi.container.servlet.ServletContainer 异常

java - 创建签名 URL 以将对象放入 Google Storage

java - 在 AppEngine Datastore (Objectify) 中定义内部类

python - 用于谷歌云数据存储的 ORM

java - 如何向 jMusic 添加 "Arabian"或 "Microtone"或 "Quarter-tone"支持?

database - 是否可以在 Google App Engine 中创建引用?