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 :

Concurrence d'accès entre 2 scripts PHP en parallèle : LOCK TABLES semble inefficace


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Par défaut Concurrence d'accès entre 2 scripts PHP en parallèle : LOCK TABLES semble inefficace
    Bonjour,

    Dans le cadre d'un projet, une page permet de réaliser un traitement. Ce dernier étant assez long, j'ai décidé de mettre en place une barre de chargement. Pour cela, j'ai créé une table "traitements" dans ma base MySQL dont chaque ligne indique un identifiant d'événement et le pourcentage effectué.

    Lorsque la page de départ est chargée, je fais plusieurs appels Ajax :
    - 1. Le premier permet de créer une nouvelle entrée de la table "traitements" dans la base. Une fois l'appel terminé, je lance deux autres appels Ajax :
    - 2.1. Un appel vers le script traitement.php , qui dure plusieurs minutes.
    - 2.2. Un appel répété, toutes les secondes, vers un script léger permettant de récupérer le pourcentage effectué pour ce traitement, afin de remplir la barre de chargement en conséquence.

    Dans mon script traitement.php, je fais des UPDATE réguliers sur la table "traitements", ce qui fait qu'en principe la barre de progression se remplit au fur et à mesure du traitement.


    Et maintenant, mon problème : les appels 2.1 et 2.2 sont bloqués. Pour empêcher la concurrence d'accès, j'ai utilisé LOCK avant la mise à jour de la table pendant le script traitement.php . Est-ce que je l'ai mal utilisé, ou alors le problème vient d'ailleurs ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $requete='LOCK TABLES chargements READ';
            mysql_query($requete);
            $requete='UPDATE traitements SET pct='.$nouvelle_valeur.' WHERE ID='.$this->id_chargement;
            mysql_query($requete);
            $requete='UNLOCK TABLES';
            mysql_query($requete);
    Merci d'avance si vous pouvez m'aider !

  2. #2
    Membre expérimenté
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Par défaut
    Ah, la joie des barres de progression... je suis content de voir que je ne suis pas le seul à qui ça cause des mots de tête . Je dois avouer que ta méthode est astucieuse, mais est ce que le lock table est vraiment nécessaire ici? Si j'ai bien compris, la table "traitements" ne contient qu'un pourcentage qui est incrémenté par ton script "traitement". Dans ce cas, la requête "update" va être quasi-instantanée et ne justifie pas l'utilisation de verrou sur la table. Le pire qui pourrait arriver c'est que ton script léger reçoive le même pourcentage deux fois de suite, ce qui n'est guère dramatique selon moi.

    Si ça peut t'intéresser, moi je m'en était sorti avec l'Output buffering de PHP. C'est une autre solution intéressante qui évite d'utiliser des tables dans la base de données.

    Donc voilà pour ça, bonne chance et... "progresse" bien he he he .

  3. #3
    Membre confirmé
    Profil pro
    aaaaa
    Inscrit en
    Novembre 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : aaaaa

    Informations forums :
    Inscription : Novembre 2006
    Messages : 178
    Par défaut
    Comment tu utilises l'output buffering dans ce cas-là ? Je l'ai utilisé pour ma part pour conserver dans une variable ce qui est normalement affiché.

    En ce qui concerne mon problème, je l'ai détourné en réécrivant mon PHP de traitement long. Je l'ai découpé, et je fais un appel Ajax à chaque fois que j'appelle un morceau de ce code (je ne suis pas sur de bien m'exprimer )
    Du coup, je n'utilise plus de base de données, mais ça fait plein d'appels d'Ajax.

  4. #4
    Membre expérimenté
    Inscrit en
    Mai 2010
    Messages
    177
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 177
    Par défaut
    Dans mon cas, j'avais un script PHP qui lisait un fichier CSV et importait les données dans une table de ma base de données. Voici en gros comment je procédais (J'ai coupé le code qui insère dans la BD pour les besoins de l'exemple):

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    <head>
    ..........
    <style type="text/css">
    .progress_wrapper {width:200px;border:1px solid #ccc;position:absolute;top:32px;left:120px}
    .progress {height:10px;background-color:#00CC00}
    .pourcent {width:200px; position:absolute; top:32px; left:330px; background-color:#FFFFFF; font-size:9px}
    </style>
    ..............
    </head
    <body>
    ob_start();
     
    $nombreLignesFichierProduit = 1;
    $numeroLigneFichierProduit = 1;
     
    $fichier = fopen($nomFichierProduit, 'r');
     
    $ligne = fgets($fichier); //On saute par dessus la première ligne d'entête
     
    //On compte le nombre de lignes dans le fichier
    //Pour pouvoir calculer le pourcentage de complétion plus loin
    while ($ligne = fgets($fichier))
    {
    	$nombreLignesFichierProduit++;
    }
    fclose($fichier);
     
    echo str_pad("Début de l'insertion<br>", 4096);
    ob_flush();
    flush(); 
     
     
    $fichier = fopen($nomFichierProduit, 'r');
     
    $ligne = fgets($fichier); //On saute par dessus la première ligne d'entête
    while ($ligne = fgets($fichier))
    {
           //Code de construction de la requête et Insertion dans BD
          .........................
     
    //Code pour la barre de progression. On fait un affichage à tous les
    //100 lignes seulement, c'est suffisant dans mon cas.
     
    if($numeroLigneFichierProduit % 100 == 0)
    	{
    		$width = (200 * $numeroLigneFichierProduit / $nombreLignesFichierProduit);
    		echo str_pad('<div class="progress_wrapper"><div class="progress" style="width:' . $width . 'px;"></div></div>', 4096);
    		echo str_pad("<div class=\"pourcent\">" . round($numeroLigneFichierProduit / $nombreLignesFichierProduit * 100) . "%</div>", 4096);
    		ob_flush();
    		flush(); 
    	}
     
    	$numeroLigneFichierProduit++;
    }
     
    echo str_pad("Importation terminée avec succès", 4096);
    ob_end_flush();
    flush();
    </body>
    Le str_pad($chaine, 4096) est très important dans mon cas, car PHP ne vas vider l'output buffer(ie faire afficher) que lorsqu'il est plein... et dans mon cas, il mesure 4096 octet. Tu peux définir la valeur par défaut dans le PHP.ini, mais normalement c'est cette valeur qui lui est donnée.

    Pour résumer, tout ce que je fais dans mon script c'est que j'écris un DIV positionné de façon absolu à l'écran. Donc, chaque echo va écrire par dessus l'ancien et la barre de progression va ainsi graduellement augmenter en largeur. C'est comme ça que je m'en suis tiré. J'espère que ce code t'aura été utile et si tu as des questions, n'hésite pas à demander .

Discussions similaires

  1. 2 scripts PHP en parallèle
    Par Ceubex dans le forum Langage
    Réponses: 8
    Dernier message: 08/06/2014, 11h47
  2. Protéger ses scripts PHP contre un accès direct
    Par PeekNPoke dans le forum Apache
    Réponses: 2
    Dernier message: 29/06/2009, 11h15
  3. Nombre d'accès concurrent à un script php
    Par canabral dans le forum Langage
    Réponses: 2
    Dernier message: 13/10/2008, 16h45
  4. entre script php et script perl
    Par isac83 dans le forum Web
    Réponses: 1
    Dernier message: 16/09/2008, 11h17
  5. Réponses: 4
    Dernier message: 16/04/2008, 11h12

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