Trouble with Transient API when W3TC is activated

I’m using W3 Total Cache 0.9.2.11 on WordPress 3.5.2. I’ve got a problem with transient API and w3tc’s object cache setting.

When I activate ‘object cache’ with memcached (other settings are default), transient APIs stop working. The behavior is: when I call get_transient() within the expiration time after set_transient(), I get null.

Read More

The behavior is consistent when ‘object cache’ is activated, and it works flawlessly when it’s deactivated. The documentation mentioned no scenario where a set_transient call might fail.

I tried the debugging mode w3tc object cache. And the page displayed some 1000 to 2000 object cache entries. I don’t quite understand the name of each entry, but my transient values aren’t there.

I’m wondering if there are any settings I have overlooked? What’s the cause of this?

Update:
I also noticed that refreshing the page will make get_transient return the desired output. It goes like this:

  1. first set_transient, get_transient returns null
  2. second set_transient, get_transient returns the first value
  3. third set_transient, get_transient returns the second value

So it looks like set_transient is taking longer to finish, is there any reference on whether w3tc have made this call asynchronous? And if so, how do I workaround it?

Related posts

3 comments

  1. I was having this same issue and was able to correct it by expanding on Andy’s solution, however I only needed to force on value in particular to not use W3TC’s object cache. I tried using APC, Memcached as well as Disk for the cache with the same results. Caching certainly helps performance, and the code I was having an issue with is not my own (a plugin) so modifying it inline was not an option…. enter filters/actions. I was able to get it working by using the following, replacing TRANSIENT_KEY with the key you want to disable caching for:

    global $_wp_using_ext_object_cache_prev;
    function disable_linked_in_cached($value=null){
        global $_wp_using_ext_object_cache;
        $_wp_using_ext_object_cache_prev = $_wp_using_ext_object_cache;
        $_wp_using_ext_object_cache = false;
        return $value;
    }
    add_filter( 'pre_set_transient_TRANSIENT_KEY', 'disable_linked_in_cached' );
    add_filter( 'pre_transient_TRANSIENT_KEY', 'disable_linked_in_cached' );
    add_action( 'delete_transient_TRANSIENT_KEY', 'disable_linked_in_cached' );
    
    function enable_linked_in_cached($value=null){
        global $_wp_using_ext_object_cache;
        $_wp_using_ext_object_cache = $_wp_using_ext_object_cache_prev;
        return $value;
    }
    add_action( 'set_transient_TRANSIENT_KEY', 'disable_linked_in_cached' );
    add_filter( 'transient_TRANSIENT_KEY', 'enable_linked_in_cached' );
    add_action( 'deleted_transient_TRANSIENT_KEY', 'disable_linked_in_cached' );
    
  2. I encountered this exact problem, and it is indeed due to W3 Cache. I deduced a way to temporarily turn off the object cache while we execute our code, which worked for my use case. The code looks like this:

    // We need to turn off the object cache temporarily while we deal with transients,
    // as the W3 Total Cache conflicts with our work
    global $_wp_using_ext_object_cache;
    
    $_wp_using_ext_object_cache_previous = $_wp_using_ext_object_cache;
    $_wp_using_ext_object_cache = false;
    
    // ...do some work with transients here...
    
    $_wp_using_ext_object_cache = $_wp_using_ext_object_cache_previous;
    

    WordPress checks the value of $_wp_using_ext_object_cache to determine if the Object Cache should be used, so we temporarily disable it while we do our work. Hope that helps somebody!

Comments are closed.