4

据我了解,这些方法中的每一个:get()put()都是原子的。

但是,当访问像 ehcache 和 memcached 这样的缓存时,CheckThenAct会出现竞争条件。

我们应该同步什么以确保如果 thread1 执行 aGet()并且 thread2 执行 aGet()后跟 a Put(),那么第一个Get()将接收到添加的新值thread2

4

2 回答 2

3

处理这种情况的方法是不缓存来自多个位置的写入或以其他方式控制访问。

一个简单的解决方案是不要从客户端对缓存进行任何写入。相反,如果您想更新值,您会触发更新值的请求。如果该值是从其他地方检索到的,那么这可以很好地工作。如果它是计算出来的或者来自客户端,那么它可能会更成问题。

与 memcache 一起使用的常见组件(至少在 PHP 世界中)是 beanstalkd 作为分布式工作队列处理器。在这种情况下,您可以将“更新缓存”请求作为工作单元触发。

如果您正在对使用现有值作为输入的缓存条目进行操作,或者如果 get-then-update 不是原子操作,则以其他方式会引入竞争条件,另一种方法是创建一个工作单元包括旧值和新值。这样,任何处理更新的进程都可以使当前值不是预期值的情况无效或以其他方式处理。

递增和递减由 memcached 接口处理,因此如果您的访问属于该类型(或可以简化为该类型的操作),那么也可以解决问题。

于 2009-09-17T02:54:24.330 回答
1

对于 memcached,您可以利用 cas() 操作在执行 put() 之前检查另一个操作是否未更新数据。

于 2011-10-11T21:57:26.420 回答