Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Transactionnel et PHP

7 réponses
Avatar
Thief13
Bonjour bonjour !
Tout le monde est levé ? bon, j'ai le truc un peut compliqué du
moment... (enfin, pour moi)

Voilà, je gere une arboresence via mysql qui est linéaire, donc, j'avais
le choix entre des fonctions récursive bien lourde, et des intervalles,
et j'ai opté pour ces derniers.

Cependant, lorsque l'on fait une insertion dans la base avec les
intervalles, ils faut faire 3 requette, et bien sur, elles doivent
toutes passer, ou aucune... donc, transactionnel.

Je sais comment faire du transactionnel avec MySQL, ce n'est pas le
probleme (enfin je croix). Non, ma question est sur php : comment, en
php, faire passer une requette transactionnel ? j'ai bien essayer
quelque chose (dont voici le code ci dessous), mais ça n'a pas l'aire de
marcher...


> if (mysql_query("BEGIN", $db_connexion)) {
>
> if (mysql_query($sql_intervalle_droit, $db_connexion) || mysql_query($sql_intervalle_gauche, $db_connexion) || mysql_query($sql, $db_connexion)) {
>
> if (mysql_query("COMMIT", $db_connexion)) {
>
> // On redirige vers la page nouvellement cree
> header("location: ".CONF_URL_ADMIN."edition/index.php?page=".mysql_insert_id());
> exit();
>
> } else {
>
> exit('Erreur l\'application des modifications, ne faite plus aucunes modifications sur le site, contacter l\'administrateur et communiquez lui le numero : '.$id_page_securise.' afin de verifier la base');
>
> }
>
> } else if (mysql_query("ROLLBACK", $db_connexion)) {
>
> exit('Erreur dans l\'une des requettes, aucune modification n\'a ete applique');
>
> } else {
>
> exit('Erreur dans l\'une des requettes et dans le ROLLBACK, ne faite plus aucunes modifications sur le site, contacter l\'administrateur et communiquez lui le numero : '.$id_page_securise.' afin de verifier la base');
>
> }
>
>
> }

Merci d'avance pour vis lanternes car là, je bloque completement. Mon
livre de référence à un paragraphe sur le transactionnel, qui dit qu'il
vaux mieux l'utiliser pour les requettes interdépendantes (sans
blagues), mais sans dire comment, j'ai bien trouvé une fonction sur le
net (qui se trouve aussi dans les commentaire de la doc php) mais je
n'arrive pas à la faire fonctionner, et je ne sais pas si elle convien à
mon cas... sinon, impossible de trouver des ressource là dessus, c'est
dingue quand meme ! personne n'a besoin du transactionnel ou quoi ?

(précision : je suis sous MySQL5, et j'utilise des tables InnoDB qui
sont normalement compatible avec le transactionnel...)

7 réponses

Avatar
Tonio
Hello,

Hum, ca doit surement être possible sans, mais avec PDO, c'est
relativement simple avec beginTransaction et rollBack :
http://fr2.php.net/manual/en/function.PDO-beginTransaction.php
Avatar
P'tit Marcel
Je sais comment faire du transactionnel avec MySQL, ce n'est pas le
probleme (enfin je croix). Non, ma question est sur php : comment, en
php, faire passer une requette transactionnel ? j'ai bien essayer
quelque chose (dont voici le code ci dessous), mais ça n'a pas l'aire de
marcher...


Si tu lis la langue de Lord Sinclair(*), cet article devrait t'aider:

http://www.devarticles.com/c/a/MySQL/Using-Transactions-with-MySQL-4.0-and-PHP/

Sinon, recopie juste le script php proposé qui devrait faire ton affaire.



(*) Clive, l'inventeur du ZX-81, pas Brett de Mission Impossible :-)
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/

Avatar
Thierry
bonjour

Voilà, je gere une arboresence via mysql qui est linéaire, donc, j'avais
le choix entre des fonctions récursive bien lourde, et des intervalles,
et j'ai opté pour ces derniers.

Cependant, lorsque l'on fait une insertion dans la base avec les
intervalles, ils faut faire 3 requette, et bien sur, elles doivent
toutes passer, ou aucune... donc, transactionnel.


Ok... donc tu veux passer une transaction mysql en php

Je sais comment faire du transactionnel avec MySQL, ce n'est pas le
probleme (enfin je croix). Non, ma question est sur php : comment, en
php, faire passer une requette transactionnel ? j'ai bien essayer
quelque chose (dont voici le code ci dessous), mais ça n'a pas l'aire de
marcher...


ça se confirme

(précision : je suis sous MySQL5, et j'utilise des tables InnoDB qui
sont normalement compatible avec le transactionnel...)


un bon point pour toi, le moteur innoDB supporte bien les transactions

mes commentaires de ton code devrait t'aider à comprendre ce que je
crois être ton erreur

if (mysql_query("BEGIN", $db_connexion)) {
la transaction est lancée

if (mysql_query() || mysql_query() || mysql_query() ) {
au moins une des 3 requête est passée

avec des && à la pace des || ce serait peut être mieux, non ?
<--------------------------
if (mysql_query("COMMIT", $db_connexion)) {
on valide la transaction

// On redirige vers la page nouvellement cree
header("location:
".CONF_URL_ADMIN."edition/index.php?page=".mysql_insert_id());

exit();
} else {
exit('erreur');
}
} else
aucune requête n'est passée

if (mysql_query("ROLLBACK", $db_connexion)) {
exit('Erreur dans l'une des requettes, aucune modification
n'a ete applique');

} else {
exit('Erreur');
}
}
} // manque ça ici je pense


sinon...
persiste et signe:
"abstrayez" vous de la BDD !!!!

ceci étant dit
http://pear.php.net/manual/en/package.database.mdb2.intro-transaction.php

ou de manière préférée si tu as accès aux exceptions:

//***********************************************************
function queryDB ($req, $db, $code) {
$res = $db->query($req);
if ( PEAR::isError($res) )
throw new Exception($res->getDebugInfo(), $code);
}

require_once('MDB2.php');
$db = MDB2::connect('mysqli://user:/db');
if ( PEAR::isError($db) )
die ('connexion à la bdd impossible');

try {
$trans = null;
if ( $db->supports('transactions')) {
$trans = $db->beginTransaction();
if ( PEAR::isError($trans) ) {
$mes = $trans->getDebugInfo();
$trans = null;
throw new Exception ($mes, $codeTransactionError);
}
} else { //au choix... ici on tente sans la transaction}

queryDB($req1, $db, $code1);
queryDB($req2, $db, $code2);
//....

if ( $trans )
$db->commit();
echo "modification de la base réussie !";
}
catch (Exception $e) {
if ( $trans ) $db->rollback();
else {
//gérer l'erreur via $e->getCode() par exemple
}
echo "modification de la base échouée avec le code {$e->getCode()}!";
}
//***********************************************************

Avatar
Thief13
avec des && à la pace des || ce serait peut être mieux, non ?


Bon sang, mais c'est bien sur !!! C'est pour ça que ça ne passait pas !
Tu penses que ça peux marcher sinon ?

Merci pour ton aide, par contre, pour pear, je préfère éviter de
l'utiliser... Ca m'a l'aire bien lourd, et pas forcément simple à mettre
en place ni à utiliser. en plus, je ne suis pas sur que ça marche sur
des hebergements mutualisé ?

Avatar
Thief13
Sinon, recopie juste le script php proposé qui devrait faire ton affaire.


En fait, je n'ai pas trouvé cet article tres clair (je le conniassi
déjà) mais je suis loin d'etre bon en anglais. en plus, ce script est le
meme que celui qui est dans les commentaire de la doc php, et c'est
celui que tout le monde à pompé sur le net pour faire son petit tuto
(toute les page que j'ai trouvé sur le transactionnel utilisait ce
script), et personnelement, j'ai un peut du mal avec, je n'arrive pas à
le faire marcher...

(*) Clive, l'inventeur du ZX-81, pas Brett de Mission Impossible :-)


Brett Sinclair, ce serait pas plutot dans "the persuaders" (amicalement
votre) ??

Avatar
Thief13
Hello,

Hum, ca doit surement être possible sans, mais avec PDO, c'est
relativement simple avec beginTransaction et rollBack :
http://fr2.php.net/manual/en/function.PDO-beginTransaction.php


Ca a l'aire simpa, je vais jeter un oeil. Mais pourquoi s'en passer ? ce
serait mieux de faire sans ?

Avatar
thierry

Bon sang, mais c'est bien sur !!! C'est pour ça que ça ne passait pas !
Tu penses que ça peux marcher sinon ?
heu oui



en plus, je ne suis pas sur que ça marche sur
des hebergements mutualisé ?


je l'ai mis en place sur free sans difficulté, ce n'est qu'une question
d'include_path.