gae单元测试hrd数据存储不一致

时间:2012-02-27 05:40:21

标签: google-app-engine google-cloud-datastore

facade.vote(datastoreRecordId, userId);
try{
    facade.vote(datastoreRecordId, userId);
    fail(); // Expect runtimeexception because voting twice is not allowed
} catch (RuntimeException ex) {}

hasVoted = facade.hasVoted(datastoreRecordId, userId);

我有一个单元测试,测试我的gae服务器的外观。 服务器在localhost上运行,每次在安装方法中擦除数据存储区。

我将一个实体放入数据存储区,然后我基本上检查它是否正确持久化!有时它会告诉我记录被发现,有时它告诉我它没有找到。 (所以hasVoted有时是真的,有时是假的,有时会抛出预期的运行时异常,有时不会抛出)

我尝试使用全局事务,本地同步和服务器端,并尝试使用单线程HttpClient。我甚至在打电话到我的门面之间睡了一些。我还尝试了appengine.xml中的线程切换。

我已经制作了一个方法,我连续100次运行测试,有时它可以工作,有时断言失败后有时在7次之后运行4次(16是记录wohoo)它是完全随机的。我只是无法找出问题所在。当我在远程appengine实例上运行测试时,一切正常,即使我在循环中运行100次。除格式c以外的任何想法:?

好吧,我发现了这个问题,我禁用了HRD并在本地转移到Master / Slave,现在一切正常!也许这篇文章可以帮助将来的某个人。任何人都理解HRD的这种行为吗?

1 个答案:

答案 0 :(得分:2)

HRD为"eventually consistent",这意味着当您编写实体时,它会异步发生:写入方法在数据实际持久存储在数据存储区之前返回。因此,如果您在写入后立即查询实体,则可能找不到它。

为什么会这样?数据存储需要一段时间才能持久化并创建索引 - 请阅读Life of a Datastore Write

注意:HRD的“最终一致性”仅影响查询。如果您put()然后get(),您应始终获得该实体。

因此,只有在使用查询时才会出现您遇到的问题。此外,此问题也应出现在生产服务器上(但您可能不会在测试设置下遇到它)。