我正在尝试使用Yii framework 1.1.12缓存从数据库检索到的一些结果。以下是我正在做的事情:
public static function getCategories()
{
if (self::$_categories !== null)
return self::$_categories;
print "Getting categories...";
self::$_categories = Yii::app()->cache->get("categoriesList");
if (self::$_categories === false)
{
$sql = "SELECT id, parent_id, name FROM {{category}} WHERE id > 0 AND is_deleted = 0";
$categoriesList = Yii::app()->db->createCommand($sql)->queryAll();
// Doing some work with $categoriesList and obtaining self::$_categories as the result
// ...
$dependency = new CDbCacheDependency("SELECT MAX(update_time) FROM {{category}}");
Yii::app()->cache->set("categoriesList", self::$_categories, 3600, $dependency);
}
return self::$_categories;
}
使用分析工具,我可以看到一切正常。在第一次执行两个查询时(每个查询一次):
SELECT MAX(update_time) FROM arrenda_category
SELECT id, parent_id, name FROM arrenda_category WHERE id > 0 AND is_deleted = 0
在进一步的请求中,只执行第一个。
问题是当我在update_time
表中增加arrenda_category
的最大值时(即使不使用我自己的编辑脚本 - 直接从MySQL命令行)并刷新页面{{1} }查询变为等于2.进一步刷新只会再次执行一次。有趣的是,如果我清除缓存,我也会执行一次SELECT MAX(update_time) FROM arrenda_category
查询。
所以我不明白为什么在条件改变时执行两次缓存依赖类的查询。我的代码或其他任何东西都有问题吗?
P.S。我确信SELECT MAX(...) ...
只能在上述功能中执行。我还看到每页请求都会找到一行SELECT MAX(update_time) FROM arrenda_category
。
答案 0 :(得分:3)
是。这是预料之中的。
<强>说明强>
假设数据已经在缓存中。当您调用函数getCategories()
时,行Yii::app()->cache->get("categoriesList")
将执行依赖查询以检查数据是否已更改。由于未更改,查询仅执行一次。
现在您已在外部更改update_time
值(或使用应用中的其他代码),然后再次调用getCategories()
,
Yii::app()->cache->get("categoriesList")
执行依赖查询以检查缓存中的数据是否有效。它发现数据无效并返回false SELECT id, parent_id, name FROM {{category}} WHERE id > 0 AND is_deleted = 0
以从数据库中获取更新的数据Yii::app()->cache->set("categoriesList", self::$_categories, 3600, $dependency);
AGAIN 执行依赖查询SELECT MAX(update_time) FROM {{category}}
以获取其结果与数据一起存储的最新MAX(update_time)
。这就是为什么查询执行两次。所以重点是每次set()
缓存一个值时,必须同时存储依赖值,因为后续的get()
查询需要它来检查依赖关系是否已更改
PS:
如果您需要更多说明,请检查set()
应用程序组件的cache
函数的源代码,它会调用evaluateDependency()
类的CDbCacheDependancy
函数,该函数将调用generateDependentData()
3}}导致执行依赖查询