La stratégie d'invalidation par défaut du plugin d'une requête du cache est
Time to Live (TTL
). Le gestionnaire de stockage interne
utilisera le TTL
par défaut, défini par la valeur de
la directive de configuration
mysqlnd_qc.ttl
à moins qu'une chaîne de requête ne contienne une astuce pour configurer
un TTL
différent. Le TTL
est spécifié
en seconde. Par défaut, une entrée du cache expire après
30
secondes.
L'exemple définit mysqlnd_qc.ttl=3
pour mettre en cache les requêtes
pour 3 secondes par défaut. Chaque seconde, il met à jour un enregistrement
d'une table de la base de données pour enregistrer l'heure courant et exécute
une requête de type SELECT
pour récupérer l'enregistrement
depuis la base de données. La requête SELECT
est mise en cache pour
3 secondes, car elle est préfixée d'une astuce SQL activant la mise en cache.
La sortie vérifie que les résultats de la requête sont prises depuis le cache
pour la durée de ces 3 secondes avant d'être mis à jour.
Exemple #1 Définir un TTL avec l'option de configuration ini
mysqlnd_qc.ttl
mysqlnd_qc.enable_qc=1 mysqlnd_qc.ttl=3
<?php
/* Connexion, création et peuplement de la table test */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id VARCHAR(255))");
for ($i = 0; $i < 7; $i++) {
/* Mise à jour de la ligne de la base de données */
if (!$mysqli->query("DELETE FROM test") ||
!$mysqli->query("INSERT INTO test(id) VALUES (NOW())"))
/* Bien sûr, un vrai script devrait avoir un gestionnaire d'erreurs meileur */
die(sprintf("[%d] %s\n", $mysqli->errno, $mysqli->error));
/* Sélection de la dernière ligne mais met en cache les résultats */
$query = "/*" . MYSQLND_QC_ENABLE_SWITCH . "*/";
$query .= "SELECT id AS _time FROM test";
if (!($res = $mysqli->query($query)) ||
!($row = $res->fetch_assoc()))
{
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
}
$res->free();
printf("Heure : %s - Heure de la ligne dans la base de données : %s\n", date("H:i:s"), $row['_time']);
/* Pause d'une seconde */
sleep(1);
}
?>
Les exemples ci-dessus vont afficher :
Heure : 14:55:59 - Heure de la ligne dans la base de données : 2012-01-11 14:55:59 Heure : 14:56:00 - Heure de la ligne dans la base de données : 2012-01-11 14:55:59 Heure : 14:56:01 - Heure de la ligne dans la base de données : 2012-01-11 14:55:59 Heure : 14:56:02 - Heure de la ligne dans la base de données : 2012-01-11 14:56:02 Heure : 14:56:03 - Heure de la ligne dans la base de données : 2012-01-11 14:56:02 Heure : 14:56:04 - Heure de la ligne dans la base de données : 2012-01-11 14:56:02 Heure : 14:56:05 - Heure de la ligne dans la base de données : 2012-01-11 14:56:05
Comme vous pouvez le voir dans cet exemple, n'importe quelle entrée du cache
basée sur un TTL
peut servir des données non mises à jour.
Les entrées du cache ne sont pas automatiquement invalidées si les données
ont été modifiées. Les applications utilisant la stratégie TTL
par défaut d'invalidation doivent être capables de fonctionner correctement
avec des données non mises à jour.
Un gestionnaire de stockage défini par l'utilisateur peut implémenter n'importe quelle stratégie d'invalidation pour permettre de s'affranchir de cette limitation.
Le TTL
par défaut peut être écrasé en utilisant l'astuce SQL
/*qc_tt=seconds*/
. L'astuce SQL doit apparaître immédiatement
après l'astuce SQL qui active la mise en cache. Il est recommandé d'utiliser la constante
PHP MYSQLND_QC_TTL_SWITCH
au lieu d'utiliser la valeur litérale.
Exemple #2 Définir un TTL avec des astuces SQL
<?php
$start = microtime(true);
/* Connexion, création et peuplement de la table test */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");
printf("TTL par défaut \t: %d seconds\n", ini_get("mysqlnd_qc.ttl"));
/* Sera mise en cache pendant 2 secondes */
$sql = sprintf("/*%s*//*%s%d*/SELECT id FROM test WHERE id = 1",
MYSQLND_QC_ENABLE_SWITCH,
MYSQLND_QC_TTL_SWITCH,
2);
$res = $mysqli->query($sql);
var_dump($res->fetch_assoc());
$res->free();
$mysqli->query("DELETE FROM test WHERE id = 1");
sleep(1);
/* Récupération depuis le cache - aucune invalidation automatique et donc, toujours valide ! */
$res = $mysqli->query($sql);
var_dump($res->fetch_assoc());
$res->free();
sleep(2);
/* Non présente en cache - l'entrée du cache a expiré */
$res = $mysqli->query($sql);
var_dump($res->fetch_assoc());
$res->free();
printf("Temps d'exécution du script\t: %d seconds\n", microtime(true) - $start);
?>
Les exemples ci-dessus vont afficher :
TTL par défaut : 30 seconds array(1) { ["id"]=> string(1) "1" } array(1) { ["id"]=> string(1) "1" } NULL Temps d'exécution du script : 3 seconds