我正在使用JDO访问数据存储区实体。我目前遇到问题,因为不同的进程并行访问相同的实体,我不确定如何解决这个问题。
我有包含值和计算值的实体:(键,值1,值2,值3,已计算)
计算发生在单独的任务队列中。 用户可以随时编辑值。 如果更新了值,则会将新任务推送到覆盖旧计算值的队列。
我目前遇到的问题是以下情况:
所以我的问题:
背景:
目前,我不介意交易表现的一致性。我会关心以后的表现。
这是我的第一个AppEngine应用程序,因为它是一个学习过程,所以它没有使用一些最佳实践。我很清楚,事后看来,我应该对我的数据模式进行更长时间的思考。例如,我的实体都没有使用适合他们的祖先关系。我来自一个关系背景,它显示出来。
我正计划进行一次重大的重构,可能会转向Objectify,但与此同时我还有一些需要尽快解决的紧急问题。我想首先完全理解数据存储区。
答案 0 :(得分:2)
显然,JDO会为事务提供乐观的并发检查(如果用户启用它),这会阻止/减少此类事件的发生。乐观并发同样适用于关系数据存储,因此您可能知道它的作用。
Google的JDO插件显然使用了低级API setProperty()方法。日志甚至会告诉您进行了哪些低级别调用(就PUT和GET而言)。转移到其他API不会自己解决这些问题。
答案 1 :(得分:2)
每当你需要在GAE中处理写冲突时,你几乎总是需要交易。但是,它不仅仅是“使用交易”这么简单:
ConcurrentModificationException
并循环重试该过程。现在当任何txn发生冲突时,它只会重试直到成功为止。这里碰撞唯一的坏处是它会减慢系统速度并在重试期间浪费精力。但是,如果您有XG事务处理吞吐量,您每秒至少会获得一个已完成的事务。
Objectify4为您处理重试;只需将您的工作单元定义为run()方法,并使用ofy()。transact()运行它。只要确保你的工作是幂等的。
答案 2 :(得分:1)
我看到它的方式,你可以阻止第一个任务更新对象,因为某些值已经从首次启动任务时发生了变化。
或者您可以在任务请求中嵌入对象的值,以便第二个计算任务将使用一致的值和计算成员恢复对象状态。