Yii Framework Forum: CDbCacheDependency subsequvent calls - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CDbCacheDependency subsequvent calls Rate Topic: -----

#1 User is offline   twisted1919 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 634
  • Joined: 23-October 10
  • Location:Romania

Posted 06 July 2012 - 11:41 AM

If i have two methods in a Post model, like

public static function a(){
  
 $dependency=new CDbCacheDependency('SELECT AVG(UNIX_TIMESTAMP(last_updated)) FROM {{post}}');
 $criteria=new CDbCriteria;
 $criteria->select='post_id,title';
 $criteria->order='post_id DESC';
 $models=self::model()->cache(1000,$dependency)->findAll($criteria);
 return $models;
            
}

public static function b(){
  
 $dependency=new CDbCacheDependency('SELECT AVG(UNIX_TIMESTAMP(last_updated)) FROM {{post}}');
 $criteria=new CDbCriteria;
 $criteria->order='post_id DESC';
 $models=self::model()->cache(1000,$dependency)->findAll($criteria);
 return $models;
            
}


Then, somewhere in a widget, let's call it widget A i call:
$models=Post::a();

then the posts will be cached, each post model having only the post_id and title attributes loaded.

Next, if in another widget, let's call it widget B, which gets called after widget A has been called, i do:
$models=Post::b();

because i want to get all the post attributes, not only the title and post_id(like i did in widget A), then i only get the post_id and the post title, because the dependency has been evaluated in Post::a() and used in Post::b() which is not correct.

How can i avoid this behavior ?
0

#2 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,047
  • Joined: 16-February 11
  • Location:Japan

Posted 06 July 2012 - 08:52 PM

View Posttwisted1919, on 06 July 2012 - 11:41 AM, said:

...
then i only get the post_id and the post title, because the dependency has been evaluated in Post::a() and used in Post::b() which is not correct.

I don't think it would ever happen, because Post::a() and Post::b() are cached in the different cache entries. Query caches uses the SQL to create the cache entry id(index).

http://www.yiiframew...a#query-caching

BTW, just out of curiosity, why 'AVG' not 'MAX'?
I mean, the sql for CDbCacheDependency must be very light-weighted because it is executed every time the cache is accessed. So I think 'MAX' is more appropriate for the purpose.
0

#3 User is offline   twisted1919 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 634
  • Joined: 23-October 10
  • Location:Romania

Posted 07 July 2012 - 02:40 PM

Quote

I don't think it would ever happen, because Post::a() and Post::b() are cached in the different cache entries. Query caches uses the SQL to create the cache entry id(index).

It does ? because it is not clear to me it does it, i mean in the docs it says that if the dependency has changed then the cache is invalidated, and basically i have same dependency for both class methods.
When you say "Query caches uses the SQL to create the cache entry id(index)." you mean the dependency sql or the actually query which should retrieve the models list ?

Quote

BTW, just out of curiosity, why 'AVG' not 'MAX'?

Honestly i don't know the answer right now, i remember i ran into troubles long time ago using only MAX and the solution that worked was AVG and i am using it since then.
0

#4 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,047
  • Joined: 16-February 11
  • Location:Japan

Posted 07 July 2012 - 04:54 PM

View Posttwisted1919, on 07 July 2012 - 02:40 PM, said:

It does ? because it is not clear to me it does it, i mean in the docs it says that if the dependency has changed then the cache is invalidated, and basically i have same dependency for both class methods.
When you say "Query caches uses the SQL to create the cache entry id(index)." you mean the dependency sql or the actually query which should retrieve the models list ?

The actual query. The hash of it is used as the cache entry id.

As the doc says, at first the cache entry is searched for.
And if the entry is found, then the validity and the dependency will be evaluated.

The dependency definition (e.g. dependency sql) and the evaluated result are both stored in each cache entry along with its contents ... that means the dependency check will be done AFTER the cache entry has been retrieved successfully.
1

#5 User is offline   twisted1919 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 634
  • Joined: 23-October 10
  • Location:Romania

Posted 08 July 2012 - 06:36 AM

Okay, thanks for explaining this, it makes sense now :)
0

#6 User is offline   twisted1919 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 634
  • Joined: 23-October 10
  • Location:Romania

Posted 08 July 2012 - 07:20 AM

Quote

BTW, just out of curiosity, why 'AVG' not 'MAX'?

I remember now why you should use AVG and NOT MAX.
If you have something like:

$dependency=new CDbCacheDependency('SELECT MAX(last_updated) FROM {{post}}');
$criteria=new CDbCriteria;
$criteria->order='post_id DESC';
$models=self::model()->cache(1000,$dependency)->findAll($criteria);
foreach($models AS $model){
 echo $model->title;
}


And let's say the above query returns 10 models, all 10 models will be cached for the next requests, but if you delete one of those 10 records from the database (not the last updated one, on which the depenency is created on by using MAX()) then in frontend you will still receive 10 models, when in fact the cache should invalidate and you should retrieve 9 models.
Makes sense ?
3

#7 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,047
  • Joined: 16-February 11
  • Location:Japan

Posted 08 July 2012 - 09:12 AM

Ah, yes, it does make sense. "MAX" doesn't reflect a deletion. I've recalled it now.
I had completely forgotten that I once got the same problem.

My workaround has been CGlobalStateCacheDependency instead of CDbCacheDependency. I store the last create, update or delete time of a table in a global state, and use it for the dependency check.
Not an elegant solution ... error-prone :(
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users