我在Java风格中使用Google Appengine,我试图执行以下操作:
1 - 创建一个属性COUNT为0的实体。
2a - 启动执行某些网络调用的任务队列任务,并更新同一实体的STATUS属性(使用Datastore#put
)
2b - 同时,在原始"线程"中,为COUNT保存不同的数字。 (也使用Datastore#put
)
鉴于2a
和2b
可能会在同一时刻并行完成,但它们会更新两个不同的属性(STATUS
和COUNT
),这些属性是否会发生冲突或抛出像并发修改异常?
答案 0 :(得分:1)
正如Igor Artamonov评论的那样,改变一个实体的一个属性仍然需要重写整个实体。考虑到这一点,你正在寻找2个实体写入,这些写入必须在事务内部完成,以防止相互覆盖。
如果在提交2b事务之前与2a中的任务enqueud相关联的事务开始,那么您描述的流将导致事务冲突。
2a任务执行被延迟 - 它将是一个请求在稍后点击你的应用程序(实际延迟取决于你当前的应用程序的负载及其可扩展性配置)。它可以<2b>比<2b>执行更长。或者它可能很小,允许2a在2b结束前开始。
我建议更改操作的顺序,使其更具可预测性,并且作为副作用,最大限度地减少事务冲突/重试的可能性: