2012-11-04 54 views
5

以這段代碼爲例: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(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/postAnotherWay重複使用相同的緩存對象,或將他們創建自己的緩存中的對象?

回答

5

我試圖在兩個不同的動作緩存相同的查詢,是的,將使用相同的緩存對象。可以看到在應用程序的配置文件中啓用了CProfileLogRoute

看一下CActiveRecord的源代碼,我說public function findByPk($pk,$condition='',$params=array())方法(和其他查詢方法)使用protected function query($criteria,$all=false)。反過來,這個終於依賴private function queryInternal($method,$mode,$params=array())CDbCommand類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); 

緩存一個評估依賴項的實例可以在public function set($id,$value,$expire=0,$dependency=null)方法CCache類中看到:

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)); 
+0

哇!沒有預料到這一級別的細節。謝謝!其中大部分是有道理的。我對這一行感到困惑:「如果指定不同的SQL來在兩個操作中創建CDbCacheDependency,則由於CDbCacheDependency的實例會與查詢的結果一起被緩存序列化,所以只有其中一個(先執行)會在緩存期間有意義」。你的意思是說,依賴實例正在被緩存和重用? – HyderA

+0

是的,我的意思是這個。將使用該值緩存依賴項實例,並在下一次在'if(($ result = $ cache-> get($ cacheKey))!<= false>'中檢索緩存值時''此實例將用於確定數據庫執行依賴關係查詢時是否發生了某些更改,並將結果與​​之前評估的結果(設置高速緩存值時)進行比較。您可以通過將'CProfileLogRoute'添加到應用程序配置的'log'組件並將'db'組件的'enableProfile'標誌設置爲'true'來測試它。 – Ezze

相關問題