具有多个服务器实例的AppEngine JDO会丢失由key提取的实体的事务更新

时间:2014-02-25 05:25:18

标签: java google-app-engine jdo datanucleus

我有一个简单的JDO测试用例,可以始终如一地重现问题: 1.两个app引擎任务几乎同时修改同一个实体 2.任务使用JDO事务并使用getObjectById加载实体 3.具有任务A修改实体上的属性A(假设A先运行) 4.让任务B修改实体上的属性B

当两个任务中的每个任务在两个不同的应用引擎实例上执行时,就会出现问题。在这种情况下,我可以看到日志消息,说任务A已将属性A正确设置为非空值并且事务已成功提交。然后,当任务B在单独的实例上运行时,它打印出它没有看到任务A对属性A所做的更改。然后任务B记录它已将属性B设置为非空值并且其事务完成成功。

然后,当我查看数据存储区时,属性A仍为null,即使我可以看到日志输出表明它已设置为非null并且事务已成功。我本来期望的两件事之一:1)当任务B加载实体时,属性A的值反映它已被设置为非空值,或者2)任务B加载过时数据,但是提交失败了“太多争用”的错误。其中任何一个都没问题。 (请注意,偶尔我会看到争用错误)

我错过了什么?看起来每个实例都有一些奇怪的缓存。我非常确定在事务中按键加载实体应反映对该实体所做的更改,即使这些更改是在单独的应用程序引擎实例上进行的。在编写测试用例以重现这一点时,我创建了全新的实体类和任务,以确保没有其他代码以某种方式解决问题并在生产中重现它(devserver提供稍微不同的行为)。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

好像你有版本问题。使用@version这将自动处理并发修改,并将抛出乐观锁定异常。