Bon, je fais un petit point sur ce sujet de transaction.
Si j’utilise un insertq_multi()
sur 200 lignes, par exemple :
- en mysql, la fonction fait des paquets de max 100 lignes et les insèrent en une instruction. Aucune gestion des transactions n’est faite, donc si le premier paquet passe et le second non on se retrouve avec un contexte final bancal.
- en sqlite, la fonction ne fait aucun paquet et exécute une seule requête qu’elle encadre par une transaction début/fin pour laquelle aucun rollback n’est effectué si la requête est en erreur. C’est déjà une différence. De ce que j’ai compris d’après les commentaires, la transaction n’est utilisée que pour améliorer les performances sqlite et non gérer la cohérence du contexte final.
Donc, conclusion : spip ne gère à aucun moment les transactions dans le but d’assurer la cohérence des exécutions multi-requêtes et comme sqlite lui est transactionnel et pas mysql ça ne permet pas d’assurer un comportement identique simplement.
Bon, alors je sais que c’est pas forcément une feature prioritaire mais je trouve que ça serait bien d’avoir un système de transactions complet et cohérent entre sqlite et mysql.
En particulier, je ne vois l’utilité de la fonction sql_preferer_transaction()
qui répond non pour mysql.
Ensuite on pourrait :
- compléter les fonctions actuelles utilisées uniquement pour sqlite
sql_demarrer_transaction()
et sql_terminer_transaction()
par une version mysql (BEGIN
, COMMIT
, c’est d’ailleurs les mêmes instructions en mysql et sqlite).
- ajouter une fonction de rollback, par exemple,
sql_annuler_transaction()
(ROLLBACK
). Pour info, il existe une méthode sqlite annuler_transaction()
.
- peut être aligner la gestion de l’insert_multi de sqlite sur celui de mysql en paquets de 100 et en gérant le fait que la transaction peut être déjà en cours
En attendant je pense utiliser sql_query() directement pour gérer les transactions