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

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

我正在使用 Java 风格的 Google Appengine,并且我正在尝试执行以下操作:

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

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

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

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

最佳答案

正如 Igor Artamonov 所评论的那样,仅更改实体的一个属性仍然需要重写整个实体。考虑到这一点,您将看到两个实体写入,这两个实体写入必须在事务内部完成,以防止相互覆盖。

如果与 2a 中排队的任务关联的事务在提交 2b 事务之前启动,您描述的流程将导致事务冲突。

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

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

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

关于java - 并发写入 GAE 数据存储实体的不同属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41565980/

相关文章:

python - 将 url 路由到 GAE Flex 服务器,而站点的其余部分在 GAE Standard 上运行

python - 发送自定义 Mime 类型 Google App Engine 电子邮件

java - 使用 OutputStreamWriter 写入 : line by line vs all at once

java - 水平添加多个列表

java - 流口水正则表达式来匹配非 Alpha

multithreading - 根据导入包(PyQt5)中打印的标准输出更新 PyQt 进度条

java - 如何使用多态性在java中制作不同类型的列表?

c - helgrind 中的 libxml2 多线程错误

c# - 使用 ContinueWith 或 Async-Await 时的不同行为

python - 我可以使用 google.api.search 匹配所有内容并仅按类别过滤吗?