6

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.

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?

2
  • I've seen this bug before - you're not crazy! It may even persist until after W3TC is disabled. A sure fix is to remove all traces of W3TC, but I realize that this is not an ideal solution.
    – Bendoh
    Jul 30 '13 at 2:35
  • Hmm... I can't, W3TC did a pretty good job with page cache and database cache. I need a dynamic persistent cache because publishing to static files is not an option for me. Maybe I should consider accessing memcached directly without wordpress?
    – He Shiming
    Jul 30 '13 at 2:46
3

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' );
3
  • That's a nice solution. So you can target specific named transients rather than targeting blocks of code.
    – Jason
    Sep 29 '15 at 12:05
  • This seems to be a very convenient solution, thx for sharing! Do you have any feedback? Are you still recommending this solution today @doublesharp?
    – rayrutjes
    Oct 1 '16 at 22:14
  • I see a comment on another answer that says that W3TC was still having this issue last year, and the code above is still in place on my website (I am using the wp-linkedin plugin and fixed for the wp-linkedin_oauthtoken transient), working as expected. Oct 2 '16 at 0:28
3

Here's the biggest problem with object caching in W3TC right now, along with a solution: http://wordpress.org/support/topic/self-diagnosed-and-fixed-w3-total-cache-bug-in-faulty-object-caching

1
  • 1
    Lone link is considered a poor answer (see help > deleted answers) since it is meaningless by itself and target resource is not guaranteed to be alive in the future. Please try to include at least summary of information you are linking to.
    – Rarst
    Jul 5 '14 at 14:20
1

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!

3
  • Well, object cache is crucial to performance. In my webapp, object cache appears to be more important than anything else, I'm not sure whether the new update of W3TC addressed this issue, but I've already been using another object cache.
    – He Shiming
    Oct 2 '13 at 7:34
  • The code I provided should only disable the object cache while you do your transient-specific work, and then it re-enables it for the rest of the app. If that would still cause performance issues, then yeah, you'll need to find something else.
    – Andy Adams
    Oct 2 '13 at 14:31
  • It's now 2015, W3TC 0.9.4.1, WP 4.3 - same issue persists and this solution works a treat. You need to switch the W3TC object cache off around all work with the transients - setting them and reading them. I've had to do this in a plugin that works fine until W3TC+memcached+object cache are configured. I was setting quite large, long-term transients (one year).
    – Jason
    Sep 29 '15 at 10:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.