避免在电子邮件服务中使用MemcacheService竞争条件

时间:2014-04-19 15:10:58

标签: java google-app-engine memcached

Image我的服务器提供了一个我正在使用memcache的电子邮件服务。当发件人向用户X发送新电子邮件时,X的密钥将从缓存中删除。当用户X调用getInbox时,响应将被添加到X的密钥下的缓存中(以便在后续调用getInbox时返回相同的响应,直到发送者删除密钥并继续进行)。所以一个非常简单的设计。但是当X在某个发件人向X发送电子邮件的同时阅读时会发生什么?根据我的理解putIfUntouched和getIdentifiable在这里没有帮助。因为它们似乎只有在我使用putIfUntouched时才能使用getIdentifiable返回的完全相同的实例/值,这在我的情况下是不可能的,因为我在谈论两个不同的服务调用。那么有人知道如何在我的简单模型中避免竞争条件吗?

更新

根据@ AndreiVolgin的回应,让我添加一些我认为是竞争条件的细节:

发件人的工作是删除密钥;收件人的工作是1)使用syncCache.get(key)读取值,2)如果值为null,则将密钥设置为syncCache.put(key, value)的实际值。问题在于send正在尝试将值设置为null,同时收件人正在调用syncCache.put(key, value)。如果收件人在设置为value时获胜,则收件人可能永远无法看到发件人所做的更改。

1 个答案:

答案 0 :(得分:0)

这不是竞争条件。用户在检查收件箱之前几毫秒内根本看不到发送给他的消息。

没有办法避免这种情况,也没有理由避免这种情况。如果在Memcache调用后1 ms发送消息而不是在此Memcache调用之前1 ms发送消息怎么办?用户不会同样心烦意乱吗?

更新:

根据OP注释,一个进程使用memcache设置一个标志(没有新的按摩),而另一个进程在新消息到达时删除它。如果新消息未能删除该标志,因为它与用户设置标志一致,则在下一条消息到达之前,新消息将不可见。

虽然非常罕见,但这是一个有效的问题。在我看来,解决方案是将标志的过期时间设置为这种罕见情况的自动防故障。