并发写入GAE数据存储区实体的不同属性

时间:2017-01-10 09:56:51

标签: java multithreading google-app-engine google-cloud-datastore concurrentmodification

我在Java风格中使用Google Appengine,我试图执行以下操作:

1 - 创建一个属性COUNT为0的实体。

2a - 启动执行某些网络调用的任务队列任务,并更新同一实体的STATUS属性(使用Datastore#put

2b - 同时,在原始"线程"中,为COUNT保存不同的数字。 (也使用Datastore#put

鉴于2a2b可能会在同一时刻并行完成,但它们会更新两个不同的属性(STATUSCOUNT),这些属性是否会发生冲突或抛出像并发修改异常?

1 个答案:

答案 0 :(得分:1)

正如Igor Artamonov评论的那样,改变一个实体的一个属性仍然需要重写整个实体。考虑到这一点,你正在寻找2个实体写入,这些写入必须在事务内部完成,以防止相互覆盖。

如果在提交2b事务之前与2a中的任务enqueud相关联的事务开始,那么您描述的流将导致事务冲突。

2a任务执行被延迟 - 它将是一个请求在稍后点击你的应用程序(实际延迟取决于你当前的应用程序的负载及其可扩展性配置)。它可以<2b>比<2b>执行更长。或者它可能很小,允许2a在2b结束前开始。

我建议更改操作的顺序,使其更具可预测性,并且作为副作用,最大限度地减少事务冲突/重试的可能性:

  • 在当前请求线程上执行2b(在事务中)
  • 在同一事务transactionally enqueue中的2a任务,只有在2b成功后才会发生。否则,您需要在2b重试期间注意潜在的多个2a任务入队。