Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 26/01/2011, 19h19   #1
Invité régulier
 
Inscription : novembre 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 67
Points : 6
Points : 6
Par défaut Accès simultanés à la base mysql

Bonjour,

Je voudrais gérer les accès simultanés à la base mysql, et mettre les clients en file d'attente lors de la modification de la base :

Code :
1
2
3
4
5
6
$sql = 'SELECT num_users FROM TABLE_USERS WHERE id="1" FOR UPDATE';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$num_users=$row[0]+1;
$sql = 'UPDATE TABLE_USERS SET num_users="'.$num_users.'" WHERE id="1"';
$result = mysql_query($sql);
si 2 personnes écrivent en même temps, est-ce que le second attend que le premier est fini avec ce code.
pol2095 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2011, 19h51   #2
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Non select for update ne fonctionne pas en stateless, tu ne peux donc pas retourner vers le php.
Il faut passer par une procédure stockée.

Par contre si le besoin est vraiment de faire num_user+1 tu peux le faire directement dans l'update:
Code :
UPDATE TABLE_USERS SET num_users = num_users+1 WHERE id=1
Et comme ça tu laisses mysql gérer le lock.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2011, 20h56   #3
Invité régulier
 
Inscription : novembre 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 67
Points : 6
Points : 6
J'ai besoin de récupérer une autre valeur entre le select et l'update, que je dois modifier et renvoyer, comment faire pour gérer les accès simultanés
pol2095 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/01/2011, 22h23   #4
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Quel est le processus global ?
Sinon pour utiliser for update il faut utiliser une procédure stockée quand on développe autour du web.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 09h26   #5
Invité régulier
 
Inscription : novembre 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 67
Points : 6
Points : 6
en fait j'ai aussi un champ qui contient du xml dans la base que je veux modifier
Code :
1
2
3
4
5
6
7
$sql = 'SELECT mon_xml FROM TABLE_USERS WHERE id="1" FOR UPDATE';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$mon_xml=$row[0];
...(ici je modifie mon xml)
$sql = 'UPDATE TABLE_USERS SET mon_xml="'.$mon_xml.'" WHERE id="1"';
$result = mysql_query($sql)
Je ne peux pas me permettre d'avoir d'accès simultané, il risquerait de manquer des données dans le champ qui contient le xml
pol2095 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 13h13   #6
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
En fait si la modification du xml est connu (je veux dire pas d'intervention via l'appli) et faisable au sein de la transaction utilisant la même connection alors je pense finalement que for update peut fonctionner.

Ce qui ne fonctionne pas c'est de proposer un écran d'édition de donnée dans une appli via for update puis après soumission du formulaire espérer faire la mise à jour, car techniquement ce sera probablement une nouvelle connection qui sera donc lockée.

De toute façon c'est assez simple à tester à priori. Il suffit de ne pas commit la transaction puis d'essayer dans une autre page de traiter le xml normalement ça devrait blocker. Par contre comme tu n'auras plus la main pour commit la 1ere transaction il faudra surement la kill pour lever le lock.

Si ça ne fonctionne pas tu peux utiliser un "lock otpimiste", par exemple ajouter une colonne timestamp que tu sélectionnes en même temps que le xml et faire l'update sur where id=1 and tstamp=$tstamp, mais dans ce cas un 2eme user peut arriver "après" traiter le xml "plus vite" et valider la transaction en 1er.

Bon je ne sais pas si je suis vraiment très clair... et j'espère ne pas avoir dis de bêtise je n'ai jamais testé le for update en php/mysql
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 19h19   #7
Invité régulier
 
Inscription : novembre 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 67
Points : 6
Points : 6
"FOR UPDATE" ne fonctionne pas avec MyISAM, il faut apparemment InnoDB qui n'est pas disponible sur les hébergements mutualisés OVH.

en utilisant "LOCK TABLES" ça a l'air de marcher
Code :
1
2
3
4
5
6
7
8
9
10
$QueryLock = 'LOCK TABLES TABLE_USERS WRITE';
$ResultLock = mysql_query($QueryLock);
$sql = 'SELECT mon_xml FROM TABLE_USERS WHERE id="1"';
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$mon_xml=$row[0];
...(ici je modifie mon xml)
$sql = 'UPDATE TABLE_USERS SET mon_xml="'.$mon_xml.'" WHERE id="1"';
$result = mysql_query($sql);
$QueryUnlock = 'UNLOCK TABLES';
QU'en pensez-vous
pol2095 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/01/2011, 20h13   #8
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
Ah oui j'étais parti du principe que vous aviez INNODB.
Effectivement LOCK TABLES peut marcher, vos tests semblent concluant, mais toute la table est blockée le temps du traitement à la GRANDE différence avec FOR UPDATE où seule une ligne est lockée.

Si cette contrainte n'est pas trop grande dans votre situation (pas trop d'utilisateurs voulant utiliser la table ) alors oui pourquoi pas, sinon regardez peut être du côté de ma proposition de lock optimiste avec timestamp.
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/01/2011, 17h36   #9
Invité régulier
 
Inscription : novembre 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : novembre 2007
Messages : 67
Points : 6
Points : 6
ce qui m'inquiète c'est la commande
Code :
$QueryUnlock = 'UNLOCK TABLES';
elle débloque toutes les tables, pas seulement la table "TABLE_USERS" que j'ai bloqué.

Est-ce que ce code fonctionne :
Code :
$QueryUnlock = 'UNLOCK TABLES TABLE_USERS';
pol2095 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 18h38   #10
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 929
Points : 1 929
D'après la doc
Citation:
UNLOCK TABLES explicitly releases any table locks held by the current session.
Qu'entends tu par "débloque toutes les tables" ? Lockes tu plusieurs tables pendant le traitement ? sinon je ne vois pas trop quel serait le problème
Qu'as tu observé ?
Je n'ai personellement jamais utilisé ce genre de "fonctionnalité".
skuatamad est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h43.


 
 
 
 
Partenaires

Hébergement Web