2012-11-04 12 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

2つの異なるアクションで同じクエリをキャッシュしようとしましたが、同じキャッシュされたオブジェクトが使用されます。アプリケーションの構成ファイルでCProfileLogRouteを有効にすることがわかります。

CActiveRecordクラスのソースコードを見ると、public function findByPk($pk,$condition='',$params=array())メソッド(および他のクエリメソッド)はprotected function query($criteria,$all=false)を使用しています。これは、最後にprivate function queryInternal($method,$mode,$params=array())CDbCommandクラスに依存しています。ここでYiiはデータベースクエリでキャッシュ処理を行います。次のように

1クエリ結果を保存し、復元するために使用されるキャッシュのキーを見ることができるように定義されます。

$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は、データベース内で何かが変更されたかどうかを判断するためにのみ使用され、キャッシュを更新するために新しいクエリが実行されます。より多くを語るには - あなたは、クエリの結果に沿って直列にキャッシュされるため、CDbCacheDependencyのインスタンスに時間をキャッシュ中に意味を行います2つのアクションそれらの一つだけ(最初に実行)でCDbCacheDependencyを作成するために、別のSQLを指定した場合:

if(isset($cache,$cacheKey)) 
    $cache->set($cacheKey, $result, $this->_connection->queryCachingDuration, $this->_connection->queryCachingDependency); 

評価した依存関係のインスタンスをキャッシュすることはCCacheクラスのpublic function set($id,$value,$expire=0,$dependency=null)方法で見ることができます。

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

うわー!このレベルの詳細は期待していませんでした。ありがとう!そのほとんどは理にかなっています。私はこの行について混乱しています: "CDbCacheDependencyを2つのアクションで作成するために異なるSQLを指定した場合、CDbCacheDependencyのインスタンスがクエリの結果と共にキャッシュされるため、キャッシング中にそのうちの1つ(最初に実行される)依存関係のインスタンスがキャッシュされ再利用されていると言っていますか? – HyderA

+0

はい、私はこれを正確に意味しました。依存関係のインスタンスは値とともにキャッシュされ、次回、 'if(($ result = $ cache-> get($ cacheKey))!== false)'条件でキャッシュ値を取り出すと、このインスタンスは依存関係のクエリを実行しているデータベースで何らかの変更が発生したかどうかを判断し、前に評価された結果と比較します(キャッシュ値が設定されたとき)。アプリケーションの設定の 'log'コンポーネントに' CProfileLogRoute'を追加し、 'db'コンポーネントの' enableProfile'フラグを 'true'に設定することでそれをテストすることができます。 – Ezze

関連する問題