【问题标题】:Concurrency with Objectify in GAEGAE 中的 Objectify 并发
【发布时间】:2012-07-05 11:10:49
【问题描述】:

我创建了一个测试 Web 应用程序来测试 Entities 的持久读取删除,我创建了一个简单的循环来持久保存 Entity,检索并修改它,然后将其删除 100 次。

在循环的某个间隔没有问题,但是有一个错误,Entity 已经存在因此无法持久化(我添加的自定义异常处理) .

同样在循环的某个时间间隔,Entity 不存在,因此无法修改,最后在某个时间间隔,Entity 不存在,无法删除。

我知道循环可能非常快,以至于对 Appengine 数据存储的操作尚未完成。因此,当尝试访问它或删除操作尚未完成时,会导致类似Entity does not exist 的错误,因此无法创建具有相同ID 的实体,依此类推。

但是,我想了解如何处理这种使用 Entity 进行并发操作的情况。

【问题讨论】:

  • 这需要更多解释......如果没有您正在做的事情的上下文,这些错误没有任何意义。但是,如果我不得不猜测,听起来您正在执行异步操作而不是完成它们。
  • @stickfigure 考虑两个线程尝试更新实体的示例,如果这两个线程几乎同时访问实体,则更新实体,比如增加一个值,然后理论上会有在两个线程中的任何一个的保存操作之后是一个缺失的增量
  • 这正是交易被发明的原因:-)
  • @stickfigure 是的,我刚从 Objectify 代码网站上看到它,我实际上实现了 DAOT 类,现在可以使用,我相信 DAOT 模式也经过了很好的测试
  • @stickfigure 然而,在阅读了 wiki 和代码之后,似乎它建立在 ConcurrentModificationException 之上以确保它不会同时持续存在,但是,在读取计数器值时,是否有应用程序尝试同时读取密钥时出现异常?

标签: google-app-engine concurrency objectify


【解决方案1】:

据我了解,您正在执行以下操作:

for i in range(0,100):
    ent = My_Entity()    # create and save entity
    db.put(ent)
    ent = db.get(ent.key())   # get, modify and save the entity
    ent.property = 'foo'
    db.put(ent)
    ent.get(ent.key())  # get and delete the entity
    db.delete(my_ent)

进行一些错误检查以确保您有要删除、修改的实体,并且您在查找要删除或修改的实体时遇到了一堆错误。正如您所说,这是因为不能保证调用按顺序执行。

但是,我想了解如何处理这种对实体进行并发操作的情况。

最好的办法是批量处理您为实体持久化所做的任何修改。例如,如果您要创建/保存/修改/保存或修改/保存/删除,请尽可能尝试组合这些步骤(即创建/修改/保存或修改/删除)。这不仅可以避免您看到的错误,还可以减少您的 RPC。按照这个策略,上面的循环将被简化为......

prop = None
for i in range(0,100):
    prop = 'foo'

换句话说,对于任何需要快速设置/删除的东西,只需使用局部变量即可。这就是 GAE 为您提供的答案。在您弄清楚所有快速的东西之后,您无法将这些信息持久保存在实体中。

除此之外,您无能为力。如果您需要确保一堆实体一起更新,Transactions 可以为您提供帮助,但如果您尝试同时对一个实体执行多项操作,则无济于事。

编辑:您还可以查看pipelines API

【讨论】:

  • 对,批量事务将适用于创建/修改/保存,还有一个我想解决的问题,即当两个线程尝试在同时,这意味着当两个线程都保存时,该值不是预期值,例如增量点函数
  • 作为一种变通方法,您可以采用 Brett Slatkin 在他的 Google IO 演讲 Building high-throughput data pipelines with Google App Engine 33:00 中建议的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多