【问题标题】:Google App Engine - Dealing with concurrency issues of storing an objectGoogle App Engine - 处理存储对象的并发问题
【发布时间】:2010-04-08 20:58:38
【问题描述】:

我想要创建并存储在数据存储中的User 对象有一个email 和一个username。在创建我的User 对象时,如何确保另一个User 对象不具有相同的email 或相同的username

如果我只是查询是否有其他用户已经使用过用户名或电子邮件,那么可能存在竞争条件。

更新: 我目前正在考虑的解决方案是使用 MemCache 来实现锁定机制。在尝试将 User 对象存储在数据存储中之前,我会获得 2 个锁。首先是一个基于email 锁定的锁,然后是另一个基于username 锁定的锁。

由于创建新的User 对象只发生在用户注册时,而且很少有人尝试使用相同的用户名或相同的电子邮件,因此我认为可以接受锁定的性能损失。

我正在考虑使用这里的 MemCache 锁定代码:http://appengine-cookbook.appspot.com/recipe/mutex-using-memcache-api/

你们觉得呢?

【问题讨论】:

    标签: google-app-engine concurrency google-cloud-datastore


    【解决方案1】:

    尝试将您的用户与他们的电子邮件一起存储为key_name。这可以通过一个简单的步骤完成:

    MyUser.get_or_insert(email)
    

    通过电子邮件获取您的MyUser 也很容易:

    MyUser.get_by_key_name(email)
    

    看到这个类似的问题:add properties to users google app engine

    这样就解决了两个用户使用同一封电子邮件的问题。要对用户名执行相同操作,请在 transaction 中执行“获取具有此用户名的用户”查询和“插入具有此用户名的用户”(这是 get_or_insert() 在幕后所做的)。

    您可以通过TransactionFailedError 查找其他用户在您的交易过程中“使用”该用户名的情况。

    绝对不想使用内存缓存互斥体,因为等待释放锁的while 循环会消耗大量内存缓存 API 调用配额。

    【讨论】:

    • 您确定我可以在同一事务中执行“获取具有此用户名的用户”查询和“插入具有该用户名的用户”吗?每个事务只能对一个实体组进行操作。要进行查询,您必须有一个祖先过滤器。 code.google.com/appengine/docs/python/datastore/…
    • 您可以查询 MyUsers 并在事务中插入 MyUser,但您不能查询 OtherThings 并在事务中插入 MyUser。可能很棘手的是,我不知道您是否可以在事务中执行get_or_insert(),因为它本身就是一个事务。在这种情况下,您需要在插入 MyUser 之前查询用户名 电子邮件可用性。
    • 我为查询设置的祖先过滤器是什么?我的User 对象都没有共同的祖先。让我的所有User 对象都有一个共同的祖先,从而使它们在同一个实体组中是不好的。
    • Spines 是对的:除非它具有祖先过滤器,否则您不能在事务中进行查询,并且此处不适用。
    • 所以没有办法在事务中做到这一点?确保两个用户最终不会使用相同的电子邮件或用户名的最佳方法是什么?
    【解决方案2】:

    如果你使用datastore的JPA impl,你只需要设置注解

    @Column(唯一=真) 字段字段

    这样,数据库将拒绝您的插入/更新..我猜它是由 gdatastore 实现的,在这种特定情况下向用户提供“技术错误”对我来说并不是什么大问题......但无论如何你可以捕获约束违反异常。我猜JDO也有这个。

    但实际上我什至不知道您使用的是 Python 还是 Java...

    据我所知,在 Java 中,您可以在事务中执行选择请求...

    关于事务,您还应该检查什么是事务隔离以及它在 GAE 上的工作原理...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 1970-01-01
      • 2018-08-21
      相关资源
      最近更新 更多