WordPress Transients APIは消えても再生成できるデータだけを一時保存する
公開日: 執筆:佐藤
WordPressのTransients APIは、再生成に時間がかかるデータを一時保存するために使います。指定した期限は、その時刻までデータが残る保証ではありません。期限より前に消えても、元の投稿、設定、外部サービスなどから作り直せるデータだけを保存します。
注文、問い合わせ、会員情報のように、それ自体が業務の記録となるデータをTransientだけへ保存してはいけません。Transientを読めなかった場合に処理を続けられないなら、保存先か設計が目的に合っていません。
Transientはoptionへ期限と再生成を加えたキャッシュにする
WordPress CodexのTransients APIは、データベースへキャッシュを一時保存する標準的な方法としてTransientを説明しています。Options APIと似ていますが、期限を指定でき、外部のオブジェクトキャッシュがあればデータベース以外へ保存される場合があります。
| 保存するもの | 使う仕組み | 読めない場合の扱い |
|---|---|---|
| サイト設定や業務記録の基になる値 | option、投稿、専用テーブルなど | 障害として復旧する |
| 投稿から集計した一覧、外部データの一時的な写し | Transient | 元データから再生成する |
optionは、後から同じ値を取り出すための保存です。Transientは、同じ計算や取得を毎回繰り返さないための写しです。速く表示するための手段と、データを所有するための保存先を分けます。
get_transientがfalseなら元データから作り直す
基本の流れは、読む、なければ作る、期限付きで保存する、利用する、の四段階です。
$cache_key = 'satolab_summary_v1';
$summary = get_transient( $cache_key );
if ( false === $summary ) {
$summary = satolab_build_summary();
set_transient( $cache_key, $summary, 6 * HOUR_IN_SECONDS );
}
satolab_show_summary( $summary );
satolab_build_summary()とsatolab_show_summary()は、流れを示すための仮の関数です。実装では、前者を投稿や外部サービスから配列を作る処理、後者をその配列から表示を作る処理へ置き換えます。架空の実案件を示すコードではありません。
get_transient()は、データがない場合と期限切れの場合にfalseを返します。数値の0や空の配列を有効なキャッシュとして使うことがあるため、==ではなくfalse === $summaryと厳密に比較します。真偽値のfalse自体を保存すると、キャッシュがない状態と区別できません。必要なら配列へ包みます。
再生成処理が失敗する可能性も分けます。外部サービスから取得できなかった場合は、失敗を示す値を業務データとしてTransientへ残さず、再試行、エラー表示、既存データの利用のどれを選ぶかを呼び出し側で決めます。
set_transientの期限は秒数で指定する
set_transient()は、キー、保存する値、期限までの秒数を受け取ります。WordPress 3.5.1では、次の形です。
set_transient( $transient, $value, $expiration );
HOUR_IN_SECONDS、DAY_IN_SECONDS、WEEK_IN_SECONDSなどの定数を使えば、6 * HOUR_IN_SECONDSのように期限の単位をコードで読めます。期限を長くするか短くするかは、元データが変わる頻度と、再生成にかかる時間から決めます。
期限を省略した場合の初期値は0です。WordPress標準のデータベース保存では、0を指定すると期限情報を作らず、自動では期限切れにしません。ただし、外部オブジェクトキャッシュから早く消える可能性は残ります。更新される写しには期限を明示し、消えないことを期待するデータはTransientへ置きません。
キーは45文字以内で用途と版を区別する
通常のTransientのキーは45文字以内にします。WordPress 3.5.1のwp_optionsでは、内部で_transient_timeout_という接頭辞を加え、64文字のoption_nameへ保存するためです。ネットワーク全体で使うsite transientのキーは、WordPress Codexが40文字以内としています。
キーは、ほかのテーマやプラグインと重ならず、何の写しか分かる名前にします。たとえば、satolab_summary_v1のように、固有の接頭辞、内容、版を短く並べます。元データの作り方を変えたときに版を変えれば、古い形式を新しい処理で読む事故を避けられます。
Transientは必ずwp_optionsにあるとは限りません。WordPress 3.5.1の実装は、外部オブジェクトキャッシュを使う場合、Transientをwp_cache_set()、wp_cache_get()、wp_cache_delete()で扱います。データベースの行を直接読まず、Transients APIを通して操作します。
元データが変わったらdelete_transientで消す
期限が残っていても、元データが変わればキャッシュは古くなります。投稿の更新、分類の変更、対象となる設定の保存など、再生成が必要になる操作でdelete_transient()を呼びます。
delete_transient( 'satolab_summary_v1' );
次にget_transient()を呼ぶとfalseが返り、同じ再生成処理へ進みます。削除後だけ別の生成処理を作ると、期限切れの場合と結果がずれます。期限切れ、早期消失、明示削除のどの場合も、一つの再生成経路へ戻します。
運用を外部へ任せる場合は、Transientのキー、元データ、期限、削除する契機、再生成処理を一組で引き継ぎます。「キャッシュを使っている」だけでは、古い表示が残る条件も、消えた後の復旧方法も分かりません。
まず、時間のかかる処理を一つ選んでください。その結果を消しても元データから作り直せるかを確認します。作り直せるなら、get_transient()の厳密比較、再生成、set_transient()、元データ変更時のdelete_transient()を一つの流れとして実装します。
関連記事

