Gcoop
Gcoop

Reputation: 3382

APC Cache Consistency Problem

I have built into our ORM layer object caching. Basically a hash of the SQL query is used as the key and the value contains the collection of objects from the DB resultset. However this creates a problem if one of the objects in the resultset is updated the cached resultset does not include the updated object. There is no write consistency. How would I implement write consistency?

Thanks

UPDATE: Currently I have an ObjectWatcher class that handles what objects are cached and their keys. Objects are cached with retrievable keys so for Person class it's Person.101 for example. The SQL query is hashed and the key maps to a Dependency object which within it has a list of the dependent objects. So SELECT * FROM person might return a Dependency object from APC which maps to Person.101 and Person.102 the resulting collection is built from this Dependency object. This works fine for the update of a single object. So If I update Person.101 and put the newly update object into APC overwriting the stale one, when a older query is run that updated object will get put into that result set, which could be incorrect. I need a way to clean not only the object from memory but all the Dependency object which hold a reference to the updated object. In APC is there a way to search for keys containing or values containing or filter keys and values?

Upvotes: 1

Views: 386

Answers (1)

user680786
user680786

Reputation:

This question is not related to APC.
You need to manage, how data will be stored in APC (or any other storage). If you want to update value of key in APC, when object will be changed - it can be possible, only when Object will know the key (hash of query) and this object should be able to collect all data from another objects, fetched by that query. All it sounds like absurd idea.

Any model should be designed with Single Responsibility principle, so if you want to cache whole objects (it's not very good idea too), then create unique keys for each object.
Also, objects shouldn't care about how they will be stored (cached), and where. So you need one more object, which will manage objects caching.

And I recommend to cache not whole objects, but only values of records in DB, which are takes to many time to fetch them from DB.

But if you still want to use hash of SQL query as a key, then you can use tags and write "names" of objects in these tags. For example, if in result-set you have objects Person, Employer and Customer, then key will have tags "person", "employer" and "customer". And, when object Customer will be changed, you can delete from cache all keys, which marked with tag "customer".
But, anyway, it's not a responsibility of Customer object, all this things should be managed by another object.

Question was edited, so I'll edit my answer too :)

Tags is not the part of APC, is the part of wrapper. Tags is very useful thing and very handy for your case.

which hold a reference to the updated object

Tags can be this reference. You don't need to search keys by tag, you need just to remove all keys associated with that tag (to keep data actual), and this wrapper has existing method to do it.

In examples:
Let we have query SELECT * FROM persons WHERE email <> '' - cached result of this query will be marked by the tag "person".

So, when we will update any Person object, we will remove all keys, which are marked with tag "person", so our result for query SELECT * FROM persons WHERE email <> '' will be removed, and in next request our script will generate new (actual) value.

Upvotes: 1

Related Questions