Caching Yii-数据库依赖项缓存是否跨多个操作工作?

Caching Yii-数据库依赖项缓存是否跨多个操作工作?,caching,yii,Caching,Yii,以这段代码为例: public function actionPostOneWay( $postId ) { $dependency = new CDbCacheDependency( 'SELECT publish_date FROM posts WHERE id = :post_id;' ); $dependency->params = array( 'post_id'=>$postId ); $post = Post::model()->cache

以这段代码为例:

public function actionPostOneWay( $postId )
{
    $dependency = new CDbCacheDependency( 'SELECT publish_date FROM posts WHERE id = :post_id;' );
    $dependency->params = array( 'post_id'=>$postId );
    $post = Post::model()->cache( 59, $dependency )->findByPk( $postId );

    // process post one way
}

public function actionPostAnotherWay( $postId )
{
    $dependency = new CDbCacheDependency( 'SELECT publish_date FROM posts WHERE id = :post_id;' );
    $dependency->params = array( 'post_id'=>$postId );
    $post = Post::model()->cache( 59, $dependency )->findByPk( $postId );

    // process post another way
}

因此,访问
/postOneWay
/postnotherway
是否会重用同一个缓存对象,或者它们会创建自己的缓存对象?

我尝试在两个不同的操作中缓存同一查询,是的,将使用同一个缓存对象。您可以在应用程序的配置文件中看到启用
CProfileLogRoute

查看
CActiveRecord
class I的源代码,说明
public function findByPk($pk,$condition='',$params=array())
method(和其他查询方法)使用
protected function query($criteria,$all=false)
。反过来,这个函数最终依赖于
CDbCommand
类的
private function queryInternal($method,$mode,$params=array())
,其中Yii使其缓存与数据库查询一起工作

可以看到,用于存储和恢复查询结果的缓存键定义如下:

$cacheKey='yii:dbquery'.$this->_connection->connectionString.':'.$this->_connection->username;
$cacheKey.=':'.$this->getText().':'.serialize(array_merge($this->_paramLog,$params));
if(($result=$cache->get($cacheKey))!==false)
{
    Yii::trace('Query result found in cache','system.db.CDbCommand');
    return $result;
}
此键不考虑缓存依赖项实例
CDbCacheDependency
仅用于确定数据库中是否有更改,以及是否要执行新查询以更新缓存。更详细地说,如果您在两个操作中指定不同的SQL来创建
CDbCacheDependency
,那么在缓存期间,只有其中一个(首先执行)是有意义的,因为
CDbCacheDependency
的实例与查询结果一起被序列化缓存:

if(isset($cache,$cacheKey))
    $cache->set($cacheKey, $result, $this->_connection->queryCachingDuration, $this->_connection->queryCachingDependency);
公共函数集($id,$value,$expire=0,$dependency=null)
方法的
CCache
class:

if ($dependency !== null && $this->serializer !== false)
    $dependency->evaluateDependency();

if ($this->serializer === null)
    $value = serialize(array($value,$dependency));
elseif ($this->serializer !== false)
    $value = call_user_func($this->serializer[0], array($value,$dependency));

哇!我没想到会有这样的细节。谢谢大部分都是有道理的。我对这句话感到困惑:“如果您在两个操作中指定不同的SQL来创建CDbCacheDependency,那么在缓存期间,只有其中一个(首先执行)是有意义的,因为CDbCacheDependency的实例与查询结果一起被序列化缓存。”。你的意思是说依赖实例正在被缓存和重用吗?是的,我的意思就是这样。依赖项实例将使用该值进行缓存,下一次在
if(($result=$cache->get($cacheKey))!==false)
条件中检索缓存值时,此实例将用于确定执行依赖项查询的数据库中是否发生了某些更改,并将结果与之前计算的结果进行比较(设置缓存值时)。您可以通过将
CProfileLogRoute
添加到应用程序配置的
log
组件,并将
db
组件的
enableProfile
标志设置为
true
来测试它。