You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress中get_transient()返回过期值:SSE插件数据更新异常求助

解决WordPress SSE进程读取旧Transient值的问题

你的核心问题是SSE长连接进程启动后,会一直复用WordPress对象缓存中的旧transient值,即便其他请求修改了transient,当前进程也无法获取最新数据。以下是几种可行的解决方案:

方案1:每次读取前清除对应transient的缓存

WordPress的get_transient会优先从对象缓存中取值,长连接进程会一直持有缓存副本。每次读取前手动清除该transient的缓存,就能强制从底层存储(数据库/外部缓存)获取最新值:

while ( true ) {
    // 清除当前进程中该transient的缓存副本
    wp_cache_delete('name_of_the_transient', 'transient');
    // 获取最新的transient值
    $latest_data = get_transient('name_of_the_transient');
    // 发送SSE事件
    $this->send_sse_event( 'updates_push', $latest_data );

    sleep( 5 );

    if ( connection_aborted() ) {
        break;
    }
}

方案2:绕过WordPress缓存层,直接查询数据库(适用于无外部对象缓存的场景)

如果你的站点没有使用Redis、Memcached等外部对象缓存,transient实际存储在wp_options表中。可以直接用$wpdb查询,完全绕过WordPress的缓存机制:

global $wpdb;

while ( true ) {
    // 直接从数据库查询最新的transient值
    $transient_key = '_transient_name_of_the_transient';
    $latest_data = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s", $transient_key ) );
    if ( $latest_data ) {
        $latest_data = maybe_unserialize( $latest_data );
    }
    // 发送SSE事件
    $this->send_sse_event( 'updates_push', $latest_data );

    sleep( 5 );

    if ( connection_aborted() ) {
        break;
    }
}

方案3:改为事件驱动(减少轮询延迟,更高效)

固定5秒轮询不仅延迟高,还浪费资源。可以让修改transient的请求触发一个"更新信号",SSE进程等待信号到来再读取数据:

步骤1:修改transient时设置信号标志

当其他请求更新transient时,同时设置一个临时的"更新标志":

// 更新transient
set_transient('name_of_the_transient', $new_data, HOUR_IN_SECONDS);
// 设置更新标志(用一个短过期的transient)
set_transient('name_of_the_transient_updated', true, 10);

步骤2:SSE进程阻塞等待信号

用sleep结合循环检查标志,直到标志存在再读取数据:

while ( true ) {
    // 等待更新标志出现,每次检查间隔1秒
    while ( !get_transient('name_of_the_transient_updated') ) {
        sleep(1);
        if ( connection_aborted() ) {
            break 2; // 跳出外层循环
        }
    }
    // 清除更新标志
    delete_transient('name_of_the_transient_updated');
    // 获取最新数据
    wp_cache_delete('name_of_the_transient', 'transient');
    $latest_data = get_transient('name_of_the_transient');
    // 发送SSE事件
    $this->send_sse_event( 'updates_push', $latest_data );

    if ( connection_aborted() ) {
        break;
    }
}

这种方式可以做到有更新才推送,延迟更低,资源占用更少。

内容的提问来源于stack exchange,提问作者fabiancdng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:33:39