Mysql, php, lock di tabelle e Cache !

Oggi, per motivi di lavoro, mi sono cimentato con la triade PHP+MYSQL+LOCK TABLE. Come dovuto, prima di fare qualsiasi esperimento da php, ho fatto qualche semplice query di prova direttamente sul mysql verificando che un "LOCK TABLES Tabella WRITE" mi impedisse, aprendo una nuova connessione, di poter fare qualsivoglia tipo di query sulla tabella in stato di Lock fino a che non l'avessi rilasciate con un bellissimo "UNLOCK TABLES". A questo punto sicuro e beato (ahhhhhh... mai fare questo quando sei seguito dalla nuvolina nera e dai famosi "Giusti Problemi" ) mi sono dedicato all'implementazione della cosa via php. Fondamentalmente il problema che volevo risolvere era negare l'accesso a una tabella di contatori da qualsiasi client se già un client la stava usando e pensavo che una volta verificata la cosa a riga di comando mi si spalancasse davanti una comoda mezz'oretta di codice per vedere la luce.

Io non sò se capita a tutti così ma per me è come una specie di abitudine, quando stò per vedere la luce succede SEMPRE qualcosa. E oggi all'angolo di aspettava il Mysql per tirarmi lo scherzo. In pratica, per impostazione di default su molte distro linux, il mysql cacha le risposte alle ultime query eseguite. Di conseguenza nel verificare il codice da me fatto mi sono trovato nella spiacevole condizione di vederlo funzionare (lokkare la tabella) o non funzionare in maniera apparentemente randomica. Mi ci è voluta una buona mezzoretta per capire che funzionava su tutte le connessioni che aprivo dopo il lock oppure sulle quali non interrogavo mai la tabella che provavo a lokkare prima di lokkarla.

E' stata un oretta divertente nella quale ho sudato freddo, non troppo, e nella quale LE HO PROVATE TUTTE. Ho provato ad usare da php una connessione persistente anziche una connessione tradizionale (per intenderci un mysql_pconnect al posto di un mysql_connect) e li per puro "culo" ha funzionato tutto alla prima ma poi appena ho cercato di far vedere la cosa a qualcuno, ovviamente, non è andata. Ho fatto poi tutta un'altra serie di ipotesi, di cui un'pò mi vergogno, tutte nella serenità del programmatore a cui il sistemista ha detto "Vai tranquillo che il mysql non cacha!". Alla fine dopo svariate prove ho capito che il problema era propio la cache e, per non dover alterare la conf di una macchina di produzione, ho trovato uno sgamo che vorrei condividere con tutti.

In pratica l'hack che ho trovato è il seguente, anziche eseguire subito le query sulla tabella oggetto di lock (dove si rischia di ottenere un risultato che viene direttamente dalla cache), si esegue la query "show table status" sul database in cui stanno le tabelle oggetto di lock. Questa query non porta risultati di cache e quindi fà da "Tappo" per tutte le query successive fino al rilascio delle tabelle e devo dire che così oggi mi sono salvato e risparmiato qualche discussione col sistemista e qualche ansia (che sarebbe sicuramente venuta nel modoficare la conf della macchina di produzione).

Vi segnalo in fine che in realtà tutto questo non dovrebbe succedere (per quanto ho capito). E' un comportamente anomalo di certe versioni del mysql, fissato nelle più recenti. In realtà il database prima di rispondere qualsiasi cosa al client dovrebbe verificare lo stato della tabelle e se è lokkata aspettare e non cercare di portarsi avanti col lavoro dando risposte, potenzialmente incoerenti, consultando la propia cache!