【问题标题】:datastore dirty reads and deletes数据存储脏读和删除
【发布时间】:2012-07-23 18:07:16
【问题描述】:

我之前已经发布了一个问题datastore: deleting entities outside transactions,但没有得到太多运气,也许我在描述问题时过于复杂,所以我会尝试用不同的问题来解决这个问题:

我没有对我的实体使用任何事务,并意识到我可能会因为脏读而丢失提交的更新,并且完全可以接受它(主要是统计数据)。我唯一需要确定的是,如果我在已经进行脏读但没有提交更新之后删除它,它不会写回该实体。我不想通过使用事务来引入争用或性能问题,因为删除很少,更新很多。

Servlet A
{
   entity = persistenceManager.getObjectById(Entity.class, key)
   //Stuff
   persistenceManager.deletePersistent(entity);
}


Servlet B
{
   entity = persistenceManager.getObjectById(Entity.class, key) // dirty read made before deletion

   //Updated some fields, after deletion was commited
   persistenceManager.flush(); ? the object would be written back
}

我已经通过在脏读和删除之间在 B 中引入 20 秒睡眠来测试上述情况,它确实将对象写回(实际上这是第一个问题的答案,将更新该问题)。

我可以依靠 memcache 让 Servlet B 在让实体知道 A 即将删除实体之前让我们说通过查看从 A 中放置的布尔缓存条目“deleting-entity-[KEY]”以及如果它是不是我不应该读取 servlet B 中的实体,我知道 memcache 不保证不驱逐数据,但如果存在,它可以从 servlet B 立即访问吗?

还有更好的想法吗?

【问题讨论】:

  • 几乎所有以“我可以依赖内存缓存”开头的问题的答案都是“否”——它是一个缓存。正如 dragonx 建议的那样,使用事务 - 除非您已经尝试对实体进行多次并行更新,否则它们不会引入争用。

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


【解决方案1】:

在 servlet B 中使用事务来验证实体是否仍然存在,然后再写入。

您为什么要避免交易?这就是事务的用途,没有它们,您无法保证任何数据同步。

【讨论】:

  • 试图避免事务我试图重新发明同样的东西,我最终将不得不使用事务,但还要改变我的模型设计以启用分片计数器以避免争用。
猜你喜欢
  • 1970-01-01
  • 2021-08-02
  • 2018-07-09
  • 2019-01-18
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多