[wp-hackers] transients API and removing stored results

Andrew Nacin wp at andrewnacin.com
Thu Mar 3 13:11:31 UTC 2011

On Thu, Mar 3, 2011 at 7:45 AM, Phillip Lord
<phillip.lord at newcastle.ac.uk>wrote:

> All of this is working well, but there is a problem. It's a development
> nightmare. There's lots of stuff in the database now that persists, and
> it's very hard to get back to a "clean" state. While I know the form of
> all the slugs used for the transients
> ("kcite_identifier_source_identifier" -- all the ids are unique by
> definition), I don't know all the slugs unless I parse all the posts, or
> do something traumatic and messy like store all the slugs as the value
> of another transient, with a single slug.
> So, my question, is it possible to delete_transients based on a
> wildcard? I could do this with a database query, but as the codex says
> "don't assume your transients are in the database". I would like to be
> able to add a "clear cache" function to the admin page for this plugin.
> Incidentally, I went this route rather than wp-cache or equivalent for a
> couple of reasons. As well as said earlier, different resolution
> attempts need different expiration times. Second, the same identifier
> can occur in several different posts; this way the data is shared
> between posts. And, finally, the plugin identifies itself to the
> resolution services; I don't the plugin to get blocked because people
> don't follow a "don't use the plugin unless you are also using wp-cache"
> instruction.

I like the use of transients here. If I was doing this though, I probably
wouldn't use them.

One, I would cache this to postmeta instead of using transients. They're
tied to posts, so it works from an implementation perspective. Assuming an
object cache is leveraged, you're not even hitting the database, but note
that postmeta is already queried for posts in the loop, so you're not really
running into performance issues either.

In this case, you will need to implement your own expiration, but that's
pretty simple, and you've already written the framework for most of that.
Like how we do this in the transient API, just store an expiration time. On
fetch, check the expiration time. (You could probably even do this on a hook
if you want to be clever.)

To clear everything, you can do a wildcard query, or even flush a post such
as on save. But in this case, you can also flush the postmeta cache for the
affected posts. (You can't do this efficiently for transients.)

I will point out that WP's internal caching mechanism *does* have an
expiration ability, but on most sites, this will never get put into a
persistent cache. Even with transients, you risk these getting flushed out
of cache, possibly earlier than necessary. Via postmeta, they're not really
going anywhere.

I'm just arguing one possible implementation. Don't turn on a dime toward
this unless you're convinced. There's always going to be many ways to do
something. For example, WP's caching of oEmbed responses also uses postmeta.
They don't expire, but probably should, and they don't use transients, but
that's been proposed. (Ticket #14749.)


More information about the wp-hackers mailing list