Plantage Apache génère des doublons

Plantage Apache génère des doublons - PHP - Programmation

Marsh Posté le 19-09-2007 à 15:29:05    

Bonjour,
 
Cela fait plusieurs mois que je planche sur le sujet et je ne m'en sors pas.
J'ai une application qui tourne avec Wamp6 :
  - Version de Apache:2.0.55 ;  
  - Version de PHP:5.1.2 ;  
  - Version de MySQL:5.0.18-nt
 
Mon problème est qu'il arrive parfois qu'à la validation d'une fiche dans l'application, un message apache s'affiche (erreur sur php5ts.dll) et sur clique de OK du message apache la fiche se retrouve en double dans la base de données.
 
J'ai fais pas mal de recherche, mis des traces dans mon code pour repérer à qu'elle moment apache plante. Apparement cela se produit au moment de l'impression (en effet à la validation de la fiche on imprime un ticket).
Il semblerait que la dll d'impression (php_printer.dll) soit corrompue ce qui provoquerait le plantage aléatoire de Apache. Et parfois la page se recharge et repasse dans le code de validation de la page...ce qui provoque le doublon...
 
Pour remédier aux problèmes de doublons j'ai changé mon code d'impression qui faisait appel à des sessions et je vais maintenant chercher les infos directement dans la base.
Voici un exemple de ce que j'ai fait :

Code :
  1. // Code de validation d'une fiche
  2. if (!empty($_SESSION['lesEstim']))
  3. {
  4. // Ouverture de la transaction
  5. mysql_query('BEGIN',$connexion);
  6. $bool = true;
  7. // On récupère les infos de l'estimation
  8. $lesEstim=new ArticleStock();
  9. $lesEstim=unserialize($_SESSION['lesEstim']);
  10. // Enregistrement d'une nouvel fiche
  11. $sql="insert into `achat` ......";
  12. $req=mysql_query($sql);
  13. if ($req==false)
  14. {
  15.  // Annulation de la transaction
  16.  mysql_query('ROLLBACK',$connexion);
  17.  die("Echec lors de l'ajout de l'achat dans la table achat ! ".mysql_error().$sql);
  18. }
  19. if (mysql_affected_rows() != -1 && $bool != false) $bool = true; else $bool = false;
  20. $ach_id = mysql_insert_id();
  21. //On ajoute les mouvements de stock et les articles dans le panier
  22. $bool = ajouter_mvt_panier(.....);
  23. // On vide les sessions
  24.             unset($_SESSION['lesEstim']);
  25. if ($bool)
  26. {
  27.  // fermeture de la transaction
  28.  mysql_query('COMMIT',$connexion);
  29.  // Impression Local des Bons
  30.  $handle = $IMP_FACTURE;
  31.  imprimer_be(......);
  32. }
  33. else
  34. {
  35.  // Annulation de la transaction
  36.  mysql_query('ROLLBACK',$connexion);
  37. }
  38. }


 
je pensais qu'en mettant en place les transactions ça résoudrait le problème et pas du tout.
Ensuite j'ai décidé de vider les sessions avant l'impression pensant que si la page se recharge et repasse dans le code de validation de la fiche, vu que la session est vidée l'enregistrement ne se fera pas.....et bien non il existe encore des doublons suite à cette erreur apache...
 
Si kelkun a compris mon problème et saurais y trouver une explication il sera le bienvenu
 
Merci

Reply

Marsh Posté le 19-09-2007 à 15:29:05   

Reply

Marsh Posté le 19-09-2007 à 16:50:00    

Tu pourrais pas plutôt utiliser PDO pour tes transactions, au lieu de ce bricolage à coups de mysql_query dont je ne suis pas sûr du tout qu'il fonctionne?[:autobot]
 
Ca sert à quoi d'affecter $bool pour l'écraser 2 lignes plus bas?
Il y a quoi autour de ce code?


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 19-09-2007 à 17:21:26    

"begin" tout court :??:
 
normalement c'est plutôt "begin trans <name>" avec <name> facultatif (et pas supporté sur tous les sgbd)
 
"begin" attends un "end", mais un "commit".
 
du coup si ça passe, à mon avis mysql l'ignore gentillement.
 
mais +1 avec skeye, il y a des chances que mysql_query() ne soit pas transactionnel, et travaille lui-même dans sa propre transaction.

Reply

Marsh Posté le 19-09-2007 à 17:22:26    

je ne connaissais pas PDO, je ne peut pas me permettre de modifier tout mon code pour le mettre en place. Ensuite pour ce qui est de mysql_query j'ai testé et mes transactions fonctionne bien.
 
Pour la variable $bool je l'initialise au départ car je la teste ensuite 2 ligne plus bas pour ensuite la réaffectée. J'ai réduis mon code pour ne ps tout afficher donc...
 
Autour de ce code il n'y a rien d'autre, quand on clique sur le bouton valider j'execute ce code

Reply

Marsh Posté le 19-09-2007 à 17:28:28    

goumag a écrit :

je ne connaissais pas PDO, je ne peut pas me permettre de modifier tout mon code pour le mettre en place. Ensuite pour ce qui est de mysql_query j'ai testé et mes transactions fonctionne bien.
 
Pour la variable $bool je l'initialise au départ car je la teste ensuite 2 ligne plus bas pour ensuite la réaffectée. J'ai réduis mon code pour ne ps tout afficher donc...
 
Autour de ce code il n'y a rien d'autre, quand on clique sur le bouton valider j'execute ce code


ouais mais ton test != false sert à rien, puisque tu l'initialise à true (constante)
 
mais bon, pour en revenir à ton problème, rien ne semble vraiment clocher dans ton code, si tu es sûr de bien vider la session.
 
ps: de toute façon, tu commit avant l'impression, donc si ça plante au moment de l'impression, c'est normal que ça merde au rechargement de la page.
 
par contre, effectivement tu sembles vider la session juste après le commit, ce qui devrait éviter le problème... du rechargement.
 
essaie quand même d'imprimer avant le commit. ou mieux, d'imprimer dans une page appelée une fois l'insertion terminée.

Reply

Marsh Posté le 19-09-2007 à 17:49:17    

Ca va surement paraitre idiot comme question, mais t'es sur que ta page n'est pas appelé deux fois par le navigateur avant même que l'impression ne se fasse? Si c'est le cas alors t'auras beau modifier $_SESSION, ça ne sera pas pris en compte par les autres exécutions qui se déroulent en même temps.
 
La prochaine fois que ça plante, regarde dans les logs d'apache s'il n'y a pas eu deux appels à la même seconde.
 
Au fait, t'es obligé d'imprimer au moment de la saisie des informations ou tu peux le faire un plus tard par le biès d'une autre page? Ca résoudrait ton problème vu que tu n'aurais plus d'impression pour faire planter le serveur au mauvais moment. (je sais, il n'y a jamais de bon moment pour un plantage. :p )

Reply

Marsh Posté le 19-09-2007 à 18:02:28    

Ma page n'est pas appelée deux fois et en plus cela se produit que lorsque le massage de l'erreur Appache s'affiche et encore parfois le message Apache s'affiche et g pas de doublon.....
 
Les logs apache, mysql et php je les ais déquortiqué des milliers de fois et g simplement "Parent: child process exited with status 3221225477 -- Restarting." :(
 
Sinon la solution d'imprimer dans une autre page je l'ai déjà fait et ça corrige pas le problème
 
En tout cas merci à tout le monde de m'aider parceque je sais vraiment plus quoi faire
 
Je viens simplement auhourd'hui de m'apercevoir que l'autocommit de mysql était toujours à 1. Je l'ai donc passé à 0 à chaque connection à la base. Je sais pas si ça va résoudre le problème...

Reply

Marsh Posté le 19-09-2007 à 18:11:37    

Citation :

Sinon la solution d'imprimer dans une autre page je l'ai déjà fait et ça corrige pas le problème


Tu veux dire que t'as fait un fichier que tu intégré au même endroit avec include (ou require ou autre équivalent) ou bien que t'avais modifié ton script pour sauvegarder les données comme actuellement mais qu'ensuite le navigateur devait demander une autre page pour imprimer le document?
Si c'est le second cas alors je ne vois pas le rapport entre le bug à l'impression et les doublons dans la page vu qu'il ne surviendraient pas en même temps.
 
Pour les logs d'apache, je ne parlais pas du log d'erreur mais du log d'accés (celui où sont noté toutes les pages demandé par qu'elle IP et quand et ce qu'il y ai eu ou non une erreur) C'est le seul endroit fiable permettant de savoir si un navigateur a demandé un ou deux exemplaire(s) de la même page.

Reply

Marsh Posté le 19-09-2007 à 18:18:16    

Citation :

Pour les logs d'apache, je ne parlais pas du log d'erreur mais du log d'accés (celui où sont noté toutes les pages demandé par qu'elle IP et quand et ce qu'il y ai eu ou non une erreur) C'est le seul endroit fiable permettant de savoir si un navigateur a demandé un ou deux exemplaire(s) de la même page.


Si tu parle du fichier access.log, c'est dans ce fichier que je me suis aperçu qu'il avait rechargé la page 2 fois. Mais je rappelle encore que l'erreur apache est complètement aléatoire.
 

Citation :

Tu veux dire que t'as fait un fichier que tu intégré au même endroit avec include (ou require ou autre équivalent) ou bien que t'avais modifié ton script pour sauvegarder les données comme actuellement mais qu'ensuite le navigateur devait demander une autre page pour imprimer le document?  
Si c'est le second cas alors je ne vois pas le rapport entre le bug à l'impression et les doublons dans la page vu qu'il ne surviendraient pas en même temps


En fait dans ma page index.php j'avais

Code :
  1. if ($_POST['valid_print'])
  2. {
  3. include('inc/valider.php');
  4. include('inc/print.php');
  5. }


Reply

Marsh Posté le 19-09-2007 à 18:48:23    

Citation :

if ($_POST['valid_print'])
{
          include('inc/valider.php');
          include('inc/print.php');
}

ok, c'est donc bien l'équivalent du code que tu nous as présenté.
 
Moi je pensais plutôt à une page (dans le sens page web, pas dans le sens fichier à inclure) qui ne contient que la partie validation avec ensuite un bouton "imprimer" (et/ou du javascript qui lance l'impression par ajax) et une seconde page qui se contente d'imprimer sans rien valider puisque tout a déjà été validé.
 
Si ta page est appelé deux fois au même moment alors on tombe bien dans le cas où on a le script qui est exécuté deux fois en simultanée avec chacun une copie des variables de sessions et ce en ignorant totalement ce que l'exécution à côté a pu modifié dans ces variables. C'est le genre de cas où aucune sécurité basé sur les sessions n'est efficace. La solution la plus simple serait de mettre un identifiant unique à chaque formulaire (ou chaque panier ou ...) afin de savoir ce qui a été validé et ce qui ne l'a pas été.
Ensuite à la validation on a deux solutions :
1) si on a une table des identifiants affecté on vérifie s'il existe dedans. S'il existe on le supprime et on fait le traitement. S'il n'y existe pas, on ne touche pas à la base (second à passer dans cette partie)
2) si on a pas de table des identifiants affecté alors il faudra vérifier si l'identifiant a été utiliser et si ça n'a pas été le cas le noter (dans une colonne de certaines tables, par exemple une colonne de la table commande, ou dans une table dédié) comme désormais utilisé.
A noter qu'il faut faire ça en dehors de toute transaction sans quoi un script qui passe avant que la transaction est validé ne pourra pas savoir si tel identifiant vient ou non d'être utilisé.
PS : Cette solution marche encore mieux si on vérouille la table des identifiant vu que ça empêchera les autres exemplaires du script de vérifier entre le moment où la vérification est faite et celle où la modification est envoyé à la base. Par contre, ça risque de ralentir l'exécution de la page s'il y a trop de monde à la fois.

Reply

Marsh Posté le 19-09-2007 à 18:48:23   

Reply

Marsh Posté le 19-09-2007 à 19:00:34    

D'un autre côté, au risque de paraître pessimiste, il subiste un risque réel qui fasse que l'ensemble de ton process est à revoir.
 
En effet, ton "bug", c'est pas simplement PHP qui arrête l'exécution après avoir trapé une erreur, mais carrément le serveur web qui redémarre.
 
Il subsiste un risque important donc : étant donné que c'est le process qui redémarre sauvagement, sans s'être arrêté proprement, il y a des chances que malgré ton appel PHP pour effacer la session, la destruction intempestive du thread PHP ne résulte pas dans sa suppression réelle. Ainsi, lorsque le process redémarre, il retrouve la session toute prête à être utilisée, comme avant le plantage.
Ainsi, tu auras beau tenter de gérer proprement le problème, il se reproduira toujours.
 
Ainsi, c'est tout ton process qui est à remettre à plat pour trouver une solution de contournement.
 
L'idée de faire un redirect et lancer l'impression sur une seconde page appelée à la fin de ton traîtement me semble la plus facile à mettre en oeuvre : cette page ne lançant qu'une impression, elle ne va pas poser de problème si elle est appelée plusieurs fois de suite.
 
Autre solution, vérifie que la ligne n'existe pas déjà au moment où tu insères la ligne... A condition que tu aies un moyen de le détecter... (tu peux te dire que le même conte client ne doit pas être capable de passer deux commande à moins de 5 minutes d'interval par exemple).

Reply

Marsh Posté le 20-09-2007 à 01:06:38    

Et pourquoi pas simplement mettre des jalons dans la session pour les insertions ou vérfier que tu as pas de doublon avant d'insérer :??:
 
Avec une transaction sans autocommit, si ça se vautre au milieu çà devrait tout planter et faire un rollback automatique au plantage (fin du script), non :??:

Reply

Marsh Posté le 20-09-2007 à 09:31:20    

Citation :


Et pourquoi pas simplement mettre des jalons dans la session pour les insertions


heu.. c quoi des jalons  
 

Citation :


L'idée de faire un redirect et lancer l'impression sur une seconde page appelée à la fin de ton traîtement me semble la plus facile à mettre en oeuvre : cette page ne lançant qu'une impression, elle ne va pas poser de problème si elle est appelée plusieurs fois de suite.


Je ne vois pas ce que vous voulez dire...

Reply

Marsh Posté le 20-09-2007 à 09:43:36    

leflos5 a écrit :

Et pourquoi pas simplement mettre des jalons dans la session pour les insertions ou vérfier que tu as pas de doublon avant d'insérer :??:
 
Avec une transaction sans autocommit, si ça se vautre au milieu çà devrait tout planter et faire un rollback automatique au plantage (fin du script), non :??:


parceque si ça fonctionne comme je le crains, pour des raisons de performances, PHP n'écrit certainement pas les modifications de la session physiquement sur le disque au moment où la modification est effectuée, mais uniquement lorsque la page a terminé son exécution (et c'est pas compliqué à faire, il suffit d'ouvrir dans un fichier bufferisé pour obtenir ce comportement).
 
résultat, si le thread est tué "salement" au milieu d'un traîtement, le fichier contenant les informations de session sera inchangé.
 
Le problème, c'est que justement le COMMIT est exécuté avant le plantage : résultat, c'est tout bien flushé en base, et c'est ensuite que php plante, avec un été des données incohérent (c'est pas seulement les requêtes qu'il faut inclure dans la transaction, mais toute la page : faire le BEGIN TRANS dès la première ligne de la page, et décider du COMMIT ou ROLLBACK à la dernière ligne du fichier).


Message édité par MagicBuzz le 20-09-2007 à 09:45:20
Reply

Marsh Posté le 20-09-2007 à 09:50:24    

goumag a écrit :

Citation :


L'idée de faire un redirect et lancer l'impression sur une seconde page appelée à la fin de ton traîtement me semble la plus facile à mettre en oeuvre : cette page ne lançant qu'une impression, elle ne va pas poser de problème si elle est appelée plusieurs fois de suite.


Je ne vois pas ce que vous voulez dire...


Je ne connais pas la syntaxe en PHP.
En ASP, c'est la méthode "Response.Redirect(<page> )"
=> Arrivé à cette ligne, cela termine l'exécution de la page proprement, sans terminer son exécution, puis ça envoie au client un header HTTP "redirect", lui indiquant de ne rien afficher, et charger immédiatement la page qu'on a passé en paramètre. Si cette fonction n'existe pas en PHP il suffit de coller un header HTTP de redirection puis arrêter l'exécution de la page pour reproduire le comportement.
 
L'intérêt du truc, c'est que si la seconde page plante, un refresh dans le navigateur ne va relancer l'exécution que de la seconde page : ainsi ton insertion en base est safe.
 
A noter toutefois un problème... Pour une raison X ou Y, il est possible qu'un client demarre exactement au moment moment deux fois ta page de traîtement. Ta méthode actuel ne permet pas de s'assurer que cela ne génèreras pas de doublons, mais le risque est limité.

Reply

Marsh Posté le 20-09-2007 à 09:51:10    

Je ne peux pas mettre le commit sur la dernière ligne du fichier car cela signifie que dès que Apache va planter la fiche ne sera jamais enregistrée. Ors je suis sur une appli qui tourne dans un magasin qui fait des ventes, le plantage apache peux intervenir jusqu'a 3 fois dans la journée et provoqué 1 ou pas du tout de doublon. Si je leur dit de ressaisir leur vente à chaque fois que l'erreur apache se produit ils vont pas être content....

Reply

Marsh Posté le 20-09-2007 à 10:28:20    

Ca vaudrait peut-être le coup de voir pourquoi apache plante. C'est pas un truc qui doit arriver souvent normalement. J'ai mis en place un intranet et il n'a jamais planté depuis 3 ans! Bien entendu, pour des questions de perfs, le serveur (Linux) est rebooté 1 fois par mois.
Tu devrais peut-être essayer une autre version de apache, php ou mysql. J'utilise wamp sur ma station de dév, les seules fois où j'ai fait planter apache, c'est en utilisant les ticks().

Reply

Marsh Posté le 20-09-2007 à 10:30:31    

C'est clair que c'est le premier truc à faire, de toute manière.[:dawao]
Modifier un programme pour pallier aux plantages de la palte-forme sur laquelle il tourne, c'est prendre le problème à l'envers...:o


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 20-09-2007 à 10:30:53    

:heink:
 
le truc plante, tu recommences la transaction. tu la gardes pas à moitié chargée en mémoire.
 
le truc, c'est de résoudre ton problème de dll foireuse, ou se trouver un autre moyen pour imprimer. certainement pas laisser volontairement un système transactionnel qui est volontairement transactionnel. tu vas à l'encontre du principe de la transaction : "si tout ce passe bien, je suis sûr que tout est bon, si y'a eu la moindre erreur, je suis sûr que j'ai rien cassé". là c'est plutôt "si y'a eu la moindre erreur, je suis sûr que j'ai tout bien cassé"...
 
quand t'es à une borne de billets SNCF, que t'as passé la commande, payé, et que tout à coup la borne se rend compte qu'elle ne peut pas imprimer le billet (donc typiquement ton cas), bah elle annule tout depuis le début, et t'es remboursé : t'as pas plus de billet qu'avant, mais au moins t'es fixé : tu sais que ta commande est pas passée.
 
là ton truc, j'ai le serveur qui crash, pas de ticket qui sort, mais aucune idée de si la transaction est passée ou non. la clôture de caisse doit être sympa le soir...


Message édité par MagicBuzz le 20-09-2007 à 10:31:00
Reply

Marsh Posté le 20-09-2007 à 10:43:37    

après chaque crash d'apache la transaction passe à chaque fois sauf que parfois elle passe deux fois. J'ai aucun problème de données érronées ou enregistrée à moitié. Les transactions fonctionnent bien.
 
Pour le plantage Apache, bien sur que j'ai cherché avant le pourquoi du plantage. Mais les logs ne m'apportent aucune information et d'après un technicien à mon boulot c'est la dll d'impression qui bug.  
J'ai bien pensé passer à une autre version de Wamp mais c pas moi qui décide... Alors pour le moment j'essais simplement de résoudre le souci des doublons

Reply

Marsh Posté le 20-09-2007 à 10:46:45    

Pourquoi tu peux pas utiliser une version antérieure de wamp :??:

Reply

Marsh Posté le 20-09-2007 à 10:52:09    

Il est vrai que le plantage est survenu au changement d'une version de mon appli. Dans cette nouvelle version, j'ai modifié le code et créé une fonction ajouter_mvt_panier(.....) dans une page function.php que j'include dans ma page index.php.
Cette fonction permet de créer les mouvements de stock selon que l'on fait un achat ou une vente. Cette fonction est assez lourde en code. Je me suis dit que peut-être cela pouvait venir de là mais dans ce cas la gestion des transactions annulerais l'enregistrement si ça plantait à ce moment là donc je me dis que c'est autre chose

Reply

Marsh Posté le 20-09-2007 à 10:54:00    

Citation :

Pourquoi tu peux pas utiliser une version antérieure de wamp :??:


Parceque ça veut dire retester toute l'appli pour voir si cela n'a pas générer de nouvelles erreurs et que c'est pas moi qui décide.

Reply

Marsh Posté le 20-09-2007 à 11:00:41    

avec php, le principal pb que tu peux rencontrer, c'est le passage de php4 à php5. Su tu reste sur un wamp à base de mysql5 et php5, y devrait pas y avoir de pb (surtout si tu utilises que les fonctions classiques de php et mysql).

Reply

Marsh Posté le 20-09-2007 à 11:18:37    

goumag a écrit :

après chaque crash d'apache la transaction passe à chaque fois sauf que parfois elle passe deux fois. J'ai aucun problème de données érronées ou enregistrée à moitié. Les transactions fonctionnent bien.


Si la transaction passe deux fois en cas de plantage, c'est que ta transaction NE MARCHE PAS.
 
Si tu colles ton commit à la fin, la première transaction sera annulée, puis la seconde, quand elle va tourner et réussir, inscrira les données dans la base proprement.
 
Ca résoud ton problème, ni plus, ni moins, tout simplement parceque tu passes d'un système transactionnel bancal à un système transactionnel correct.
 
Le transactions, ça s'applique à un process, pas seulement aux données MySQL.

Reply

Marsh Posté le 20-09-2007 à 11:22:39    

goumag > Si c'est juste la dll qui merde, pourquoi tu n'essaie pas une version plus récente de ce fichier? Cette dll fait partie des extensions PECL donc il faut récupérer une version de PECL.
La dernière stable se trouve sur le site de php http://www.php.net/downloads.php  
Sur le site http://snaps.php.net/ t'as des versions remises à jours plusieurs fois par jours (donc toutes les corrections de bugs y sont mais il n'y a pas moyen d'être sur de l'absence de nouveaux bugs)
 
La version actuelle de php est la 5.2.4 est du coup les paquet pecl actuel correspondent à un serveur en 5.2. Il faut donc vérifier sur un serveur de test qu'il n'y a pas de problème de compatibilité avec un php 5.1.
 
Si tu ne peux pas utiliser de version plus récente de cette dll alors il faut que t'arrêtes de faire l'impression en même temps que la création de la facture.

Reply

Marsh Posté le 20-09-2007 à 11:22:52    

rufo a écrit :

Pourquoi tu peux pas utiliser une version antérieure de wamp :??:


Et pourquoi pas simplement mettre à jour la DLL avec une version plus récente/ancienne ?
Il y a peut de chances que la DLL propose une interface incompatible s'il reste dans la même version majeure, et ça a toutes les chances de solutionner le problème.
 
Surtout, isoler qui est l'éditeur de la DLL, et aller faire un tour sur le support. Si le bug est connu, il y a de fortes chances pour que :
1/ Un solution de contournement soit proposée
2/ Un correctif soit disponible
 
(grillé - saloperie de cnx internet qui merde au boulot :o)


Message édité par MagicBuzz le 20-09-2007 à 11:23:27
Reply

Marsh Posté le 20-09-2007 à 16:21:22    

Sur le lien http://pecl4win.php.net/ext.php/php_printer.dll on peut télécharger la dll php_printer.dll
 
Seulement moi ma version de php est 5.1.2 et le site propose la dll pour php version 5.1.6 ou 5.1.2.
 
Est-ce que je peux tenter la version pour php 5.1.6 ?

Reply

Marsh Posté le 20-09-2007 à 16:30:21    

Et pourquoi tu ne pourrais pas ?
 
Ethiquement, le développeur doit s'imposer la compatibilité ascendante, ou largement prévenir lorsqu'une fonctionnalité n'est plus supportée d'une version à l'autre.
 
En gros, toute nouvelle version peut être mise en place d'une version ancienne sans risques de régressions, sauf mention contraire.
 
Ici c'est juste un changement de sous-sous-version, c'est à dire très certainement des corrections, le périmètre fonctionnelle devrait même pas être changé.
 
Au pire... Bah t'attends un soir, tu mets la nouvelle DLL, et si ça plante, tu remets l'ancienne... Ca va pas faire brûler ton PC...


Message édité par MagicBuzz le 20-09-2007 à 16:31:13
Reply

Marsh Posté le 20-09-2007 à 16:31:19    

Tu peux tenter la 5.1.6 sans crainte mais en commençant quand même par la tester sur un serveur de test.
Dans les numéros de versions de php, le dernier chiffre indique juste le numéro de version publique dans la branche indiqué par les deux premiers chiffres. En gros, php 5.1.6 est une 5.1.2 avec beaucoup de bugs corrigé et quelques changements mineurs qui ne sont censé poser aucun problème de rétrocompatibilité.
 
EDIT : Ce coup ci c'est moins qui me suis fait griller.


Message édité par omega2 le 20-09-2007 à 16:34:44
Reply

Marsh Posté le 20-09-2007 à 16:33:13    

ok je vais tenter ça et on verra ce que ça donne
 
En tout cas merci à tout le monde :)

Reply

Marsh Posté le 21-09-2007 à 05:40:16    

Un jalon c'est un point de repère dans un processus. Genre: la saisie du besoin est exprimé, le traitement est fait, l'impression est ok = tout c'est bien passé.
 
Dans le cas contraire s'il manque un point, tu annules tout. C'est ce que magicbuzz te dit en te parlant de transaction ua niveau général (sans se limiter au sgbd)
 
Faudrait donc que si ça coupe à n'importe quel moment t'arrive à reprendre le cours ou à défaut on considère que tout a foiré et on annule tout!
 
Ca peut se produire dans pleins de cas: coupure courant sans secours, coupure réseau, arrêt de la transaction en cours de route pas l'opérateur, plantage du PC client, plantage du serveur...
 
Pour faire ça, si on peut pas se fier aux sessions (à vérifier), faut tracer en base après exécution de l'action et rediriger pour vérifier que tout va bien. Et surtout passer par une phase de cloture finale, si on y arrive pas on annule tout (tu vas me dire quand, comment, ça c'est à définir selon le fonctionnement de ton appli: par client/connecté, par tâche de fond...)

Reply

Marsh Posté le 26-09-2007 à 14:47:19    

Bon j'ai installer ma correction sur l'autocommit et la dernière dll de php_printer de la version 5.1 de php et ça n'a rien changé. Le client à toujours les erreur apache et s'est retrouvé avec un doublon samedi.
 
Je vais donc mettre en place ce que m'a conseillé MagicBuzz à savoir éxécuter l'impression dans une autre page.
 
Voilà ce que j'ai fait :
Dans ma page index.php j'ai mis :
- au début de la page :

Code :
  1. // Clique sur "Valider" ou "Valid + Impr"
  2. if ($_POST['valid'] || $_POST['valid_print'])
  3. {
  4. include('inc/valider.php');  // Enregistrement des données
  5. $code_doc = $vent_id;    // Récupération de l'identifiant de la fiche
  6. if ($_POST['valid_print'] && $vente_bool) // Si l'utilisateur à cliquer sur valider + imprimer et que l'enregistrement s'est bien passé on lance l'impression à la fin de la page
  7.  $imprimer = true;
  8. }


- à la fin de la page

Code :
  1. if ($imprimer)
  2. {
  3. echo "<script language='JavaScript' type='text/JavaScript'>";
  4. echo "MM_openBrWindow('../inc/impression.php?typedoc=VEN&codedoc=".$code_doc."&numavoir=".$new_avoir."&tabreg=".$_SESSION['regbaav']."','impression','scrollbars=yes,resizable=yes,width=700,height=400,top=100,left=200');";
  5. echo "</script>";
  6. }


 
J'ai créé une page impression.php avec ce code :
 

Code :
  1. // initialisation des variables
  2. $type_doc = $_GET['typedoc'];
  3. $code_doc= $_GET['codedoc'];
  4. $action = $_GET['action'];
  5. $num_avoir  = $_GET['numavoir'];
  6. $tab_reg = unserialize($_SESSION['regbaav']);
  7. // Impression du ticket de caisse, dans tous les cas, sauf pour l'avoir.
  8. if ($num_avoir=="" )
  9. ticket($IMP_FACTURE, $code_doc, $TRAIT);
  10. else
  11. imprimer_ba($IMP_FACTURE, $num_avoir, "CREA", $TRAIT);
  12. <script language="JavaScript" type="text/JavaScript">
  13. window.close();
  14. </script>


 
En gros quand l'utilisateur valide une fiche, j'enregistre les données puis à la fin de la page j'ouvre la fenêtre impression.php qui execute l'impression du ticket puis je ferme la fenetre.
 
J'explique tout ça car MagicBuzz m'avait dit de faire une redirection de la page sur une page d'impression puis de revenir sur l'ancienne page de validation. Je voulais savoir si l'a façon dont je l'ai fait c'est bien la page impression.php qui sera rechargée et non index.php en cas d'erreur Apache ? (oui parceque mon problème c'est que je n'arrive pas à reproduire le problème sur mon poste je doit donc à chaque fois installer mes modifs chez le client et prier pour qu'il n'y est pas de doublon...)

Reply

Marsh Posté le 26-09-2007 à 14:52:15    

si c'est bien la page impression.php qui plante, oui, ton problème est résolu.
 
j'aime pas trop ta méthode de redirection, mais bon, ça marche aussi bien qu'un entête http à condition que le navigateur client n'aie pas un truc qui bloque le js (vu que c'est pur de l'informatique interne, tu maîtrises la configuration des postes, donc c'est pas un problème).

Reply

Marsh Posté le 26-09-2007 à 14:56:25    

ok merci je vais voir ce que ça donne

Reply

Marsh Posté le 26-09-2007 à 14:57:50    

D'où la question que j'ai déjà posé plus haut mais d'une autre manière : t'es sur que personne ne fait de double clic sur le bouton de validation?
 
Si tu savais le nombre d'utilisateurs qui sont incapable de faire la différence entre "c'est une page web donc je dois cliquer qu'une fois" et "c'est l'explorateur de fichier donc je cliques deux fois", tu serais franchement étonné.
 
Pour avoir eu à faire une maquette de site web en delphi3 il y a 6 ans, je peux te dire que ça peut être l'horreur totale ce genre d'utilisateur.

Reply

Marsh Posté le 26-09-2007 à 14:59:53    

j'avais pas fait gaffe à un truc.
 
utiliser plutôt un window.navigate() plutôt que l'ouverture d'une nouvelle fenêtre : en cas de plantage, l'utilisateur risque de fermer la popup et recharger la page principale... ce qui reproduira la même erreur.
 
le but du jeu, c'est que l'utilisateur soit complètement redirigé vers cette page d'impression : si ça plante, il relance l'impression, mais ne relance pas l'enregistrement de la commande.

Reply

Marsh Posté le 26-09-2007 à 15:01:57    

omega2 a écrit :

D'où la question que j'ai déjà posé plus haut mais d'une autre manière : t'es sur que personne ne fait de double clic sur le bouton de validation?
 
Si tu savais le nombre d'utilisateurs qui sont incapable de faire la différence entre "c'est une page web donc je dois cliquer qu'une fois" et "c'est l'explorateur de fichier donc je cliques deux fois", tu serais franchement étonné.
 
Pour avoir eu à faire une maquette de site web en delphi3 il y a 6 ans, je peux te dire que ça peut être l'horreur totale ce genre d'utilisateur.


je viens de penser à un autre truc...
le comportement classique de l'utilisateur face à une erreur c'est "page précédente" ("recharger la page", connait pas)
- planté
- page précédente
- valider le formulaire à l'identique de la première fois
 
=> si par malheur la page précédente reconstruit la session, y'a 9 chances sur 10 pour que c'était ça la raison du problème

Reply

Marsh Posté le 26-09-2007 à 15:17:04    

interessant le coup du "Page précédente", dès que je l'ai au téléphone je lui pose la question.
 
Pour le double clique j'ai fait des tests et c'est pas possible car quand l'utilisateur clique sur "Valider", j'affiche un message "Voulez-vous vraiment valider cette fiche ?".

Reply

Marsh Posté le 26-09-2007 à 15:26:47    

Citation :


j'avais pas fait gaffe à un truc.  
 
utiliser plutôt un window.navigate() plutôt que l'ouverture d'une nouvelle fenêtre : en cas de plantage, l'utilisateur risque de fermer la popup et recharger la page principale... ce qui reproduira la même erreur.  


 
Ok t'as raison je vais plutot faire ça :)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed