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

Requêtes MySQL Discussion :

Collisions de requetes sur bdd MySQL


Sujet :

Requêtes MySQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut Collisions de requetes sur bdd MySQL
    Bonjour le forum!

    J'ai le probleme suivant:

    J'ai lu a plusieurs endroits que la protection contre la collision de deux requetes sur une base de données est bien meilleure que celle fournie par la fonction php flock pour le verrouillage des fichiers. Donc on nous conseille d'utiliser de préférnces les bdd que les fichiers pour stocker les données.
    Donc j'ai décidé de faire une systeme personnalisé de verrouillage des fichiers par stockage du nom du fichier dans une bdd mysql (et aussi car flock ne marche pas pour toutes les fonctions d'ecriture et de lecture dans les fichiers).

    Voila le probleme: le blocage d'un fichier se fait par inclusion de son nom qui est une clé primaire dans la bdd. Or apparemment parfois il se produit deux écritures en meme temps sur le fichier donc deux requetes d'inclusion du nom de fichier dans la bdd sont entrées en collision (si elle n'etaient pas rentrées en collision, la premiere aurait été acceptée mais pas le deuxieme car clé primaire). Est-ce possible?

    NB:voila comment j'ai vérifié produit la collision: le script php qui se trouve sur un serveur distant (chez un hébergeur) est sollicité par moi par deux ordis différents, et ce script contient une boucle qui écrit 5000 fois (assez pour que les deux appels au script se superposent) sur le meme fichier (en rajoutant le texte a la fin du fichier). Le texte obtenu montre un mélange des données rentrées et des caractere non reconnus ????? preuve qu'il y a eu superposition. Je me disais q'etant donné qu'on effectue les requetes a la vitesse d'exécution du programme il est normal qu'il y ai des collisions de requetes dans la bdd. Mais j'ai fait un test avec flock a la place du verrouillage par bdd et avec flock on a légerement moins de superpositions...?

  2. #2
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Salut,

    Tu as tenté un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (!$fini) {
       if (mysql_query ("INSERT INTO latable VALUES ('$nom_fichier')")) {
         fopen ($nomfichier, "a");
         fwrite(...);
         mysql_query("DELETE FROM latable WHERE ...");
         $fini = true;
       }
    }
    Ceci dit j'y vois un gros défaut de PHP qui ne sait pas se reposer sur le système de fichiers sous-jacent pour gérer les accès concurrents...

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    en gros oui (avec un usleep(100) dans la boucle, pour attendre 0.1 secondes avant le prochain essai).

    Par contre je ne suis pas sur d'avoir compris ta remarque...
    Tu veux dire que php ne sais pas gérer les acces concurrents a...un fichier? Si c'est ce que tu veux dire, c'est justement pour ca que j'utilise une base de données, car selon ce que j'ai lu elles gerent mieux les acces concurrents (moi j'ai appelé ca collision de requetes :o) )

    Mais ce qui m'etonnes, c'est qu'avec la base de donnée j'ai toujours des collisions (moins que sans systeme de verrouillage, mais autant qu'avec flock).

  4. #4
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par lysandre Voir le message
    Par contre je ne suis pas sur d'avoir compris ta remarque...
    Tu veux dire que php ne sais pas gérer les acces concurrents a...un fichier?
    Oui, PHP ou le système de fichiers (NTFS...) ce qui serait encore plus surprenant.

    Concernant tes collisions tout ce que je peux dire c'est qu'une contrainte de clé primaire ou unique est inviolable donc tant que le DELETE n'a pas été fait, pas d'autre insertion dans la base.

    Peut-être que fwrite() est fait de telle façon que le script continue en séquence alors que le travail d'écriture s'exécute toujours en parallèle ? Dans ce cas ça pourrait expliquer que le fichier soit encore en cours d'écriture même après le DELETE.

    Tu as essayé en combinant flock() et la méthode base de données ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par Maximilian Voir le message
    Peut-être que fwrite() est fait de telle façon que le script continue en séquence alors que le travail d'écriture s'exécute toujours en parallèle ? Dans ce cas ça pourrait expliquer que le fichier soit encore en cours d'écriture même après le DELETE.
    Ca aurait pu etre possible effectivement, mais j'ai fait le petit essai suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $link=fopen("fichier.txt","w+");
    echo microtime()." ";
    fwrite($link,$texteassezlong);
    echo microtime();
    echo file_get_contents("fichier.txt");
    et le texte entier m'a été affiché (donc au moment ou est exécuté le file_get_contents tout le texte a été ecrit par le fwrite). Le texte $texteassezlong est au moins aussi long que les textes avec lesquels j'ai eu des collisions. Apres il y a toujours possibilité que le script php continue et que toutes les requetes sur le fichier soient mises a la queue en parallele...
    La différence des microtime donne en moyenne sur plusieurs essais 0.2 microseconde quand le texte est long, 0.13 microsecondes quand le texte est court...ce n'est pas fulgurant comme différence, mais ca laisse penser que le fichier php attends le fin de l'exécution du fwrite. D'ailleur fwrite retourne une valeur suivant le succes ou l'echec de l'opération, donc je pense que le script php attends l'exécution du fwrite avant de continuer.

    Peut-etre que la base de donnée peut avoir des faiblesses si elle recoit des enchainements de requetes de deux scripts différents et a la cadence d'exécution du code php...?

    Je pense que je vais pouvoir tester ca, car j'ai introduit une sécurité de plus dans mon systeme de verrouillage: quand un utilisateur ajoute le nom du fichier dans le base de données, il y ajoute en plus un code généré aléatoirement, attends 30 microsecondes, et vérifie que le code qui est dans la base de donnée est bien le sien. Si c'est le sien, le verrouillage est effectif et il peut commencer a ecrire sur le fichier. Si ce n'est pas le sien, cela veut dire que deux requetes "insert" son passées en meme temps (car sa requete insert est passée, et si le code n'est pas le sien, une autre requete insert est aussi passée avec la meme clef primaire) et ca m'envoie un message d'erreur. Quand j'aurai testé ce code je reviens ecrire les resultats!

  6. #6
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par lysandre Voir le message
    Peut-etre que la base de donnée peut avoir des faiblesses si elle recoit des enchainements de requetes de deux scripts différents et a la cadence d'exécution du code php...?
    Cela provoquera un rejet d'un des deux INSERT qui essaient d'insérer le même nom de fichier, au pire des deux s'ils sont réellement "simultanés", mais jamais une acceptation des deux à la fois qui serait une violation de la contrainte d'unicité.

    Pour t'en persuader, remplace tes fichiers par une table contenant les données et tes fwrite() par des UPDATE. Non seulement il n'y aura plus de problèmes de "collision" (données qui seraient le mélange d'un bout de modification et d'un bout d'une autre) mais il n'y aura jamais non plus deux clés primaires de même valeur.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Je crois que j'ai cerné une cause possible du probleme de mon code mais je n'arrive pas a savoir pourquoi ca se passe comme ca:

    Dans le code j'utilise des usleep(100), or j'ai fait un essai en entourant le usleep() de deux microtime(), et le usleep(100) semble ne pas marcher, la différence de temps enregistrée par les microtime() est négligeable (de l'ordre de 0.1 ms) au lieu de 100ms...?
    Ca ne marche ni sur le serveur de mon hébergeur (ovh) ni chez moi (easyphp et je suis sous windows mais je pense que ma version de easyphp, 1.8.0.1, supporte le php 5 dc normalement pas de pb).
    Par contre sleep marche avec des valeurs entieres de secondes.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Bon, j'ai compris pourquoi mon usleep ne marche pas, je croyais que son parametre s"exprimait en millisecondes :o)

    J'ai fait des essais et vérifié que les bases de données sont bien béton en ce qui concerne le collision de requetes, meme avec des requetes faites a la cadence d'exécution d'un script. Donc la seule explication restante est celle que tu as donné meme si ca parait pas trop probable...je ne sais pas si c'est possible de faire un test pour savoir de facon sure si l'ecriture/lecture dans les fichiers se déroule en parallele avec l'exécution du script...?

  9. #9
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Peut-être comparer l'horaire de fin du script et la date de dernière modification du fichier dans le système d'exploitation, lors d'une grosse écriture dans un fichier ?

    Ceci dit ça me parait effectivement étrange, on a souvent de grosses applications type serveur qui crachent des milliers de lignes à la seconde dans leurs fichiers de log et jamais on ne constate de collision...

    Peut-être que PHP n'est pas le langage le plus adapté pour ça ?

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    J'ai fait le test que tu proposes, je ne sais pas quoi penser du resultat.
    Quelque soit la taille du texte que j'ecris dans le fichier, j'obtiens toujours deux secondes de différence entre la date de derniere modification obtenue avec filemtime() et la fin de l'execution du script php obtenue avec microtime().

    De plus quand j'ecris dans un fichier et aussitot apres dans le meme script quand je lis ce fichier,


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    echo "<br>".microtime();
     
    $link=@fopen("fichier.txt","w");
     @fwrite($link,"");
    @fclose($link);
     
     
    echo "<br>".microtime();
    $cont=@file_get_contents("fichier.txt");
    echo "<br>".microtime();
    echo $cont;
    le contenu qui ressort est bien celui qui a été écrit. J'ai pensé que toutes les requetes ecriture et lecture sur un fichier étaient mises a la queue, en parallele avec le script php, mais ce n'est pas possible car la lecture du fichier doit etre en phase avec le script. Et l'exécution du file_get_contents() n'est pas retardée pour attendre la fin de l'ecriture puisque la différence entre les deux derniers microtime() est la meme qu'on ecrive ou pas avant.

    Donc je ne sais toujours pas ce qui se passe...

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    le texte du fwrite n'est bien sur pas vide ;o)

  12. #12
    Membre à l'essai
    Inscrit en
    Juin 2006
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 18
    Points : 14
    Points
    14
    Par défaut
    Peut-être devrais-tu utiliser un table de priorité (id auto-increment).
    Avant de réaliser ton insertion, tu insere une demande dans la table des priorité.

    Dans une boucle tu testes le rang de ta demande dans la table des priorité.
    Si l'id de ta demande est le plus petit, tu sors de la boucle et tu fais ton insertion, puis tu effaces ta demande dans la table des priorités.

    Cela devrait fonctionner. Une seule demande ne peut donc être réaliser en même temps.

    En espérant avoir été clair.

    Oxi

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    meme le code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $link=@fopen("fichier.txt","w");
     @fwrite($link,$texte);
    @fclose($link);
     
    clearstatcache();
    echo filemtime("fichier.txt");
    echo "<br>".microtime();
    donne un filemtime("fichier.txt") avec deux secondes de PLUS que le microtime() qui le suit !!?

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par oxilab Voir le message
    Peut-être devrais-tu utiliser un table de priorité (id auto-increment).
    Avant de réaliser ton insertion, tu insere une demande dans la table des priorité.

    Dans une boucle tu testes le rang de ta demande dans la table des priorité.
    Si l'id de ta demande est le plus petit, tu sors de la boucle et tu fais ton insertion, puis tu effaces ta demande dans la table des priorités.

    Cela devrait fonctionner. Une seule demande ne peut donc être réaliser en même temps.

    En espérant avoir été clair.

    Oxi
    Oui merci Oxilab c'etait clair. Je ne penses pas que ca regle le probleme, car en ce qui concerne mon probleme ce que tu proposes ne fait pas de différence avec ce que je fais deja:
    J'ai pu vérifier que les actions dans les scripts php sont bien ordonnées, c'est a dire que l'ecriture dans le fichier par un script php ne se fait jamais avant que l'autre script ait fini d'écrire. Donc théoriquement pas de superposition. Mais en fait des spuerpositions se produisent, ce qui a fait dire a Maximilian que peut-etre l'ecriture continue meme apres que la fonction fwrite ait été exécuté, et donc continue en parallele avec le script.

    C'est a dire:
    1-debut écriture par script 1
    2-fin "virtuelle" (fwrite exécutée) écriture par script 1
    3-debut écriture par script 2
    4-fin réelle écriture par script 1 (impossible a tester?) =>superposition des deux écritures

    Avec ce que tu suggeres, comme avec mon systeme, a l'etape 2- le script 1 libere la base de données et le script 2 peut commencer a ecrire, se superposant avec l'ecriture par le script 1 qui n'est en fait pas finie.
    Mais selon les tests que j'ai fait, cette explication semble ne pas tenir...et je ne comprends pas ce qui se passe.

    Je vais tout de meme essayer ce que tu suggeres, on ne sait jamais.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    non ca ne marche pas non plus. Il y a toujours superposition des écritures. Ce qui est tres surprenant est qu'il y a superposition même quand attends 2s entre deux écritures!!
    De plus le contenu du fichier ne corresponds pas a l'ordre des actions effectuées sur le fichier...je n'y comprends plus rien!

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Je met le code si jamais vous avez envie d'y jeter un oeil...
    Ici le variable $type défini le type de verrouillage: 1 en lecture, 0 en écriture.

    -Si le fichier est verrouillé en lecture d'autres personnes peuvent le lire, mais pas y écrire
    -si le fichier est verrouillé en écriture, personne ne peut y lire et y ecrire a part celui qui a verrouillé le fichier.

    La fonction de verrouillage s'appelle "bloquer", la fonction de deverrouillage s'appelle "débloquer". Elles appartiennent a une classe a laquelle fait référence $this. En particulier $this->url est l'url du fichier (vous l'auriez deviné).

    Ces fonctions utilisent aussi la classe "connexion" qui gere les contacts avec la base de donnée, et j'en utilise les fonctions:

    ->del($condition,$table) qui effacer les enregistrements de $table satisfaisant $condition

    ->add($variables,$valeurs,$table) insere un enregistrement dans $table

    ->isreturn($consition,$table,$retour) cherche dans $table 1 seul enregistrement satisfaisant $condition et retourne un tableau contenant les colonnes de la table précisées dans $retour

    ->select($table) effectue toutes les opérations nécessaires (connection a mysql, etc) nécéssaires pour lire dans la table $table
    voila le code des fonctions de (dé)verrouillage:
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    function bloquer($type=0){
    $i=0;
    $arr=explode("/",$this->url);
    $this->nom=$arr[count($arr)-1];
    if ($type){
     
     
    if ($this->permis1 || $this->permis) return true;
     
    $this->a->del('nom="'.$this->nom.'" and date<'.(time()-10),"block");
    $this->code=rand(0,900000000);
     
    $ok2=$this->a->add("nom,type,date,code",'"'.$this->nom.'",1,'.time().','.$this->code,"block");
     
    $ok3=$ok2 && ($arr=$this->a->isreturn('nom="'.$this->nom.'" and code='.$this->code,"block","num"));
     
    $ok=$ok3 && ($sortie=@mysql_query('SELECT * FROM block WHERE nom="'.$this->nom.'" and num<'.$arr["num"]));
     
    if ($ok){
    while ($elem=mysql_fetch_array($sortie)){
    $ok= $ok && $elem["type"];
     
    }
     
    }
     
    $this->a->close("block");
    $ok && ($this->permis1=1);
     
    while(!$ok){
    usleep(100000);
    $i++;
     
    if (!$ok2){
    $ok2=$this->a->add("nom,type,date,code",'"'.$this->nom.'",1,'.time().','.$this->code,"block");
     
    }
    if (!$ok3){
    $ok3=$ok2 && ($arr=$this->a->isreturn('nom="'.$this->nom.'" and code='.$this->code,"block","num"));
     
    }
     
    $ok=$ok3 && ($sortie=@mysql_query('SELECT * FROM block WHERE nom="'.$this->nom.'" and num<'.$arr["num"]));
    if ($ok){
    while ($elem=mysql_fetch_array($sortie)){
    $ok= $ok && $elem["type"];
     
    }
     
    }
     
    $this->a->close("block");
    $ok && ($this->permis1=1);
    $ok=($i > 99 ) || $ok;
    }
    $ok2 && !$this->permis1 && $this->a->del('nom="'.$this->nom.'" and code='.$this->code,"block");
    return $this->permis1;
     
    } else {
     
    if ($this->permis) return true;
     
    $this->a->del('nom="'.$this->nom.'" and date<'.(time()-10),"block");
    $this->code=rand(0,900000000);
     
    $ok2=$this->a->add("nom,type,date,code",'"'.$this->nom.'",0,'.time().','.$this->code,"block");
     
    $ok3=$ok2 && ($arr=$this->a->isreturn('nom="'.$this->nom.'" and code='.$this->code,"block","num"));
     
    $ok=$ok3 && ($sortie=@mysql_query('SELECT * FROM block WHERE nom="'.$this->nom.'" and num<'.$arr["num"])) && (!mysql_fetch_array($sortie));
     
    $ok && ($this->permis=1);
    $this->a->close("block");
     
     
    while(!$ok){
    usleep(100000);
    $i++;
     
    if (!$ok2){
    $ok2=$this->a->add("nom,type,date,code",'"'.$this->nom.'",0,'.time().','.$this->code,"block");
     
    }
    if (!$ok3){
    $ok3=$ok2 && ($arr=$this->a->isreturn('nom="'.$this->nom.'" and code='.$this->code,"block","num"));
     
    }
     
    $ok=$ok3 && ($sortie=@mysql_query('SELECT * FROM block WHERE nom="'.$this->nom.'" and num<'.$arr["num"])) && (!mysql_fetch_array($sortie));
     
    $this->a->close("block");
    $ok && ($this->permis=1);
    $ok=($i > 99 ) || $ok;
    }
    $ok2 && !$this->permis && $this->a->del('nom="'.$this->nom.'" and code='.$this->code,"block");
    return $this->permis;
    }
     
     
    }
     
     
    function debloquer($type=0){
    $arr=explode("/",$this->url);
    $this->nom=$arr[count($arr)-1];
     
    if (!((!$type && $this->permis) || ($type && $this->permis1 && !$this->permis))) return false;
     
    sleep(2); // ce sleep sert a attendre entre deux modifications du fichier
    $ok=$this->a->del('nom="'.$this->nom.'" and code='.$this->code,"block");
     
    $this->a->close("block");
    if ($ok) {
    $this->permis1=0;
    $this->permis=0;
    }
    return $ok;
    }
    apres pour le test en gros je fais une boucle avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for ($i=0; $i < 400 ;$i++){
    $file->bloquer(0);
    fwrite(...,"a");
    $file->debloquer(0);
    }
    Je fais exécuter ce script en meme temps par deux ordinateurs (moi et un ami) qui n'ont pas la meme connection internet (sinon il n'y a pas d'acces concurrents)

    Voila, si vous voyez un pb...

  17. #17
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Je te conseille de faire un tour dans les commentaires utilisateurs sur la page http://fr2.php.net/manual/fr/function.flock.php , c'est assez édifiant sur la fiabilité des fonctions de manipulation de fichiers de PHP.

    Il parait clair que dans un environnement transactionnel intensif la solution adéquate est de stocker l'intégralité des données dans une base relationnelle (c'est en autres pour ça qu'elles ont été créées). Est-ce que tu es vraiment obligé d'utiliser des fichiers ?

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Points : 68
    Points
    68
    Par défaut
    Je ne peux pas utiliser de bases de données car l'espace dans les bdd MySQL qui m'est alloué chez mon hebergeur n'est largement pas assez grand.


    Dans le premier commentaire quelqu'un propose d'ailleur de copier le contenu du fichier dans un fichier temporaire, le modifier et apres test avec filemtime() remplacer le fichier par le fichier temporaire modifié. Le probleme est que meme filemtime ne semble pas marcher correctement, dans le sens ou l'ecriture dans le fichier (ou le remplacement d'un fichier par un autre) semble continuer apres que filemtime() ai recu une nouvelle valeur correspondant a la modif en cours...

    En fait tout se passe comme si pendant l'exécution du script les modif faites au fichier étaient gardées en mémoire temporaire mais pas forcément écrites dans le fichier tout de suite.

    Voila un exemple frappant de résultat que j'ai obtenu pendant mes tests (je rappelle que je fais tourner deux script, l'un ecrit "premier".$i a la fin du fichier, ou $i est un compteur dans une boucle, l'autre écrit "deuxieme".$i. A la fin des écritures le contenu du fichier est affiché

    Théoriquement le contenu a la fin devrait ressembler a ca:

    premier1 premier2 .... deuxieme5 premier 37 premier38 deuxieme6 ...etc

    Mais un essai a donné ca:

    -le premier script retourne:
    premier 1 premier2 ???premier6 premier7???? ect ou les points d'interrogation sont dus a des erreur d'ecriture dans le fichier, et aucun "deuxieme" n'est présent.

    -le deuxieme script qui tournait en meme temps retourne:
    deuxieme1 deuxieme2.....deuxieme10???? deuxieme11.... donc aucun "premier"!!!

    -le contenu du fichier apres écritures par les deux scripts est identique a ce qu'a retourné le premier script, surement car le premier script a écrit en dernier. Pour moi ce resultat est incompréhensible: comment le contenu du fichier ne peut contenir a la fois que des "deuxieme" et que des "premiers"? la reponse pourrait etre que le script n'ecrit pas forcement tout de suite dans le fichier, donc chacun fait ses ecritures de son coté dans une memoire temporaire et a un moment ils décident de rentrer le contenue dans le fichier. Mais alors pourquoi les ??? dans le fichier? Bref, je ne comprends pas grand chose...

Discussions similaires

  1. problème de requete sur BDD
    Par madcode dans le forum Android
    Réponses: 5
    Dernier message: 24/11/2011, 06h11
  2. Triggers sur BDD MySQL de Free
    Par Superleo2999 dans le forum MySQL
    Réponses: 4
    Dernier message: 14/05/2010, 19h13
  3. Réponses: 4
    Dernier message: 13/07/2009, 15h37
  4. [MySQL] Requete insertion BDD mysql
    Par mjs21 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 19/06/2008, 08h53
  5. DBexpress, Simple requete sur server MySql
    Par Ice-tea dans le forum Bases de données
    Réponses: 7
    Dernier message: 02/06/2006, 14h57

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