IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

UPDATE suivi d'un SELECT, mauvais synchronisme ?


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de FrankOVD
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juin 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2005
    Messages : 438
    Par défaut UPDATE suivi d'un SELECT, mauvais synchronisme ?
    Bonjour,

    SITUATION :

    J'ai développé une application Web où se situe un formulaire à partir duquel on peut modifier des informations pour un produit et lorsque l'événement "onUnload" est appelé, la page appele en AJAX un script PHP qui effectue une requête UPDATE dans la base de données.

    PROBLÈMATIQUE :

    Que la requête update soit appelée pour un rafraîchissement de la page pour pour retourner à ma liste des produits, la page suivante n'affiche pas les informations à jour. Ainsi, il faut que je rafraîchisse ma page à nouveau pour voir les bonnes informations.

    QUESTION :

    Est-il possible dans ce cas que la requête d'UPDATE n'aie pas terminé son exécution alors qu'une requête SELECT est appelée dans la page suivante ou existe-t-il une autre situation qui pourrait causer ce problème. Si oui, comment pourrais-je corriger la situation?

    PISTES :

    1 - Même si je fait attendre ma première page jusqu'à ce que l'exécution du script PHP qui appelle ma requête UPDATE soit terminée, le problème reste entier.

    2 - Peu importe la page où je me retrouve et la requête SELECT qui est appelée, l'information retournée n'est pas à jours.

    3 - J'ai appelé mes pages avec des paramètres générés aléatoirement pour écarter la possibilité d'une mauvaise gestion de la cache.

  2. #2
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    J'ai pas tout compris ton enchaînement de pages...

    Tu peux nous poster les bouts de code qui concernent ton problème ?

  3. #3
    Membre éclairé Avatar de FrankOVD
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juin 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2005
    Messages : 438
    Par défaut
    D'accord,

    Voici comment ça fonctionne. Le tout est déclanché onUnload. La fonction save_final() appelle save_produit() qui appelle en AJAX le code PHP plus bas. Ensuite bien entendu la page se décharge et le navigateur charge la nouvelle page où les informations ne seront pas à jour...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    function save_final() {
      if(document.forms['mod_produit'].unsaved.value > 0) {
        save_recette();
        var msg = "Souhaitez-vous enregistrer les modifications?\n\nCliquez sur OK pour enregistrer les modifications\nCliquez sur ANNULER pour quitter sans enregstrer";
        if(confirm(msg)) {
          save_produit("all");
          alert("Enregistrement terminé");
        }
      }
    }
     
    /**
     * Enregistre les informations relatives à un produit. 
     * Si le paramètre obj est un objet, l'enregistrement sera fait spécifiquement pour cet objet.
     * Si cependant obj == "all", toutes les informations relatives au produit seront enregistrées
     * Paramètre : obj
     **/
    function save_produit(obj) {
      //AJAX
      xmlHttp=GetXmlHttpObject();
      if(xmlHttp==null) {
        alert("Browser does not support HTTP Request")
        return
      }
     
      var id_produit = document.forms['mod_produit'].id_produit.value;
     
      if(obj == "all") {
        var frm = document.forms['mod_produit'];
        var cible = "produits.php?action=modifier&all="+id_produit;
        cible += "&code_produit="+escape(frm.code_produit.value);
        cible += "&desc_fr="+escape(frm.desc_fr.value);
        //...						
        $asynchronous = true;
        xmlHttp.open("GET",cible,$asynchronous); //change to true for asynchronous
        xmlHttp.send(null);
      }
      else {
        //...
      }
      return true;
    }
    Code PHP
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    $query  = "UPDATE produits ";
    $query .= "SET code_produit  = ".mysql_safe(urldecode($_GET["code_produit"])).",";
    $query .= "    desc_fr       = ".mysql_safe(urldecode($_GET["desc_fr"])).",";
    $query .= "    desc_en       = ".mysql_safe(urldecode($_GET["desc_en"])).",";
    $query .= "    poids         = ".mysql_safe(urldecode($_GET["poids"])).",";
    $query .= "    volume        = ".mysql_safe(urldecode($_GET["volume"])).",";
    $query .= "    qte           = ".mysql_safe(urldecode($_GET["qte"])).",";
    $query .= "    qte_piece     = ".mysql_safe(urldecode($_GET["qte_piece"])).",";
    $query .= "    prix_vente_1  = ".mysql_safe(urldecode($_GET["prix_vente_1"])).",";
    $query .= "    prix_vente_2  = ".mysql_safe(urldecode($_GET["prix_vente_2"])).",";
    $query .= "    prix_vente_3  = ".mysql_safe(urldecode($_GET["prix_vente_3"])).",";
    $query .= "    prix_vente_4  = ".mysql_safe(urldecode($_GET["prix_vente_4"])).",";
    $query .= "    prix_vente_5  = ".mysql_safe(urldecode($_GET["prix_vente_5"])).",";
    $query .= "    gl_inventaire = ".mysql_safe($_GET["gl_inventaire"]).",";
    $query .= "    gl_vente      = ".mysql_safe($_GET["gl_vente"]).",";
    $query .= "    gl_achat      = ".mysql_safe($_GET["gl_achat"])." ";
    $query .= "WHERE id_produit  = ".mysql_safe($_GET["all"]);
    if(!mysql_unbuffered_query($query)) {
      queryErrorReport("La modification du produit #".$_GET["all"]." à échoué", $query, mysql_error(), basename(__FILE__), __LINE__);
      exit;
    }
    else {
      echo("Enregistrement terminé");
      return true;
    }

  4. #4
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Ajax, comme son nom l'indique d'ailleurs, est utilisée de manière asynchrone.
    ça veut dire que ton appel ajax part, et que le code javascript continue son chemin. Et le chemin amène à... unload !
    Donc on a, en parallèle, 2 requêtes simultanées qui partent vers le serveur. L'une va faire un update, l'autre, visiblement, fera un select. Mais rien ne te garantie qu'une des requêtes va arriver ou être traitée avant l'autre.

    Plusieurs solutions s'offrent à toi:
    - utilisation de messages synchrones (bad idea, le navigateur est bloqué le temps de la requête)
    - annulation du unload (arrêt de l'événement) en cas de sauvegarde. Ce qui te permettra d'afficher le feedback comme quoi l'update c'est bien passé ou pas, ce qui n'était pas le cas visiblement.

  5. #5
    Membre éclairé Avatar de FrankOVD
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Juin 2005
    Messages
    438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Juin 2005
    Messages : 438
    Par défaut
    Bonjour,

    J'ai essayé de plusieurs façon d'éviter la situation que tu décris. C'est à dire que je l'ai essayé de façon Synchrone sans résultat. J'ai aussi fait une boucle qui ralentissait le navigateur jusqu'à l'obtention du readystate 4 (complete). Dans les deux cas, bien que Javascript air attendu un certain moment avant le unload, la situation reste la mème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    xmlHttp.open("GET",cible,$asynchronous); //change to true for asynchronous
    xmlHttp.send(null);
     
    //Pour tests, synchronous manuel
    if($asynchronous == false) {
      var loop = 0;
      while(xmlHttp.readyState < 4) {
        loop = loop + 1;
      }
    }
    Pour ce qui est d'annuler le unload, tout ce que j'en sais c'est qu'il est impossible de le faire à moins d'appeler un événement géré par le navigateur qui fait afficher une page du genre "Voulez vous fermer la page?". Je ne souhaite pas que mes utilisateurs aient à répondre à une telle question car il ignoreront pourquoi ils ont à le faire.

  6. #6
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Citation Envoyé par FrankOVD Voir le message
    Pour ce qui est d'annuler le unload, tout ce que j'en sais c'est qu'il est impossible de le faire à moins d'appeler un événement géré par le navigateur qui fait afficher une page du genre "Voulez vous fermer la page?". Je ne souhaite pas que mes utilisateurs aient à répondre à une telle question car il ignoreront pourquoi ils ont à le faire.
    il te suffit de leur expliquer. en effet, tu captures l'événement onBeforeUnload et tu rajoute à l'événement un message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    evt.returnValue = "Vous n'avez pas sauvegardé vos modifications.";
    Ce message sera automatiquement affiché dans la fenêtre de confirmation du navigateur. (en tout cas Fx et IE)

    ça répond pas au besoin initial mais fournit une solution de contournement.
    Sinon t'as pas une version de test hébergée en ligne pour nous permettre de tester ?

Discussions similaires

  1. [AC-2000] UPDATE Table Set Field = Select Count(*). Possible ?
    Par DocDen dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 02/07/2009, 10h20
  2. update avec jointure et selection
    Par funboard dans le forum SQL
    Réponses: 1
    Dernier message: 28/01/2009, 16h29
  3. MySQL: Probleme d'UPDATE avec sous requete SELECT
    Par simonius dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/11/2007, 14h57
  4. [oracle 9i]update à partir d'une selection complexe
    Par Requin15 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 13/06/2006, 10h18
  5. Réponses: 15
    Dernier message: 20/12/2004, 10h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo