Problème pour experts!

Consultez la formation à Google Analytics de WebRankInfo / Ranking Metrics

chameau
Nouveau WRInaute
 
Messages: 34
Inscription: Mar Mar 16, 2004 9:48

Problème pour experts!

Message le Lun Jan 31, 2005 12:20

Voila j'ai développé un jeu en php. Il y a une section marché qui permet de vendre et acheter des objets. Elle fonctionne bien tant qu'il n'y a pas trop d'utilisateur. Le nombre d'achats est limité à 20 par jour par utilisateur.

Un problème surgit quand il y a beaucoup d'utilisateurs connectés (+250), et que le serveur subit quelques ralentissement. Si quelqu'un clique frenetiquement sur le lien des dizaines de foi avant le chargement de la page, il arrive à faire plus de 20 achats!

dans ma bd, nbachats arrive à des résultats négatif.

succintement, voici le code:

Code: Tout sélectionner
$query = "SELECT nbachats FROM utilisateur WHERE id='$idmembre'";
$result= mysql_query($query);
$row = mysql_fetch_row($result);
if($row[0]<20){

$query = "UPDATE utilisateur SET nbachats=nbachats+1 WHERE id='$idmembre'";
$result = mysql_query($query);

//mes differentes operations

}

Comment cela est-il possible?
Y a-t-il une solution?

Merci

French Fred
WRInaute impliqué
WRInaute impliqué
 
Messages: 265
Inscription: Jeu Fév 12, 2004 18:19

Message le Lun Jan 31, 2005 12:37

Salut,

Sur la page qui est la cible du lien, tu devrais faire un flush .

Code: Tout sélectionner
echo ' ';
flush();


Le echo permet d'ecrire quelque chose sur la page.
Le flush, renvoi le contenu de la page definie avant l'instruction "flush".
http://fr.php.net/flush

Cordialement,

FRed


tom_pascal
WRInaute impliqué
WRInaute impliqué
 
Messages: 278
Inscription: Lun Nov 17, 2003 13:58

Message le Lun Jan 31, 2005 12:48

Bonjour,

très intéressant ce problème de concurrence.

une instruction flush ne va faire que forcer l'envoie du buffer vers le navigateur, mais cela ne va pas permettre de gérer le problème si ce script est par exemple appelé deux fois simultanément (pile poil) par un utilisateur qui en est à 19 achats... ou je me trompe ?

Pour ma part, j'essaierais de faire le SELECT avec une priorité plus faible que la requete de mise à jour (UPDATE), histoire que celle-ci passe prioritairement dans le cas où plusieurs requêtes s'éxecutent simultanément..

Je ferais donc un truc comme ça pour vérifier le nbachats de l'utilisateur :
$query = "SELECT LOW PRIORITY nbachats FROM utilisateur WHERE id='$idmembre'";

De toutes facons, cela ne réglera pas les problème dans 100% des cas, mais je pense que la probabilité pour qu'il se manifeste devrait être diminué ?

Si tu essayes ma solution, tu me tiens au courant chameau STP ?


rituel
WRInaute accro
WRInaute accro
 
Messages: 1176
Inscription: Sam Mar 15, 2003 23:58

Message le Lun Jan 31, 2005 13:41

Faudrait utiliser un flag que tu passes à 1 dès que la requête est traitée. Si le flag est à 0 alors je traite la requête, sinon je traite pas. Ainsi tes requêtes dupliquées ne seront pas traitées.


herveG
Modérateur
Modérateur
 
Messages: 9834
Inscription: Mer Mar 05, 2003 11:33

Message le Lun Jan 31, 2005 13:55

y a des mecs qui vivent dans un autre monde.... :)


GAMING ZONE
WRInaute passionné
WRInaute passionné
 
Messages: 533
Inscription: Ven Aoû 13, 2004 20:06

Re: Problème pour experts!

Message le Lun Jan 31, 2005 13:59

Code: Tout sélectionner
$query = "SELECT nbachats FROM utilisateur WHERE id='$idmembre'";
$result= mysql_query($query);
$row = mysql_fetch_row($result);
if($row[0]<20){
$nbachats=$row[0]++;
$query = "UPDATE utilisateur SET nbachats='$nbachats' WHERE id='$idmembre'";
$result = mysql_query($query);
//mes differentes operations
}
else {
$query = "UPDATE utilisateur SET nbachats='20' WHERE id='$idmembre'";
$result = mysql_query($query);
}


Il y a un truc qui me chiffone, tu indique avoir nbachats negatifs ...
Dernière édition par GAMING ZONE le Lun Jan 31, 2005 14:07, édité 2 fois.


Americas
WRInaute accro
WRInaute accro
 
Messages: 3380
Inscription: Mer Sep 24, 2003 11:49

Message le Lun Jan 31, 2005 14:01

herveG a écrit:y a des mecs qui vivent dans un autre monde.... :)


Comme toi herveG... bon... on va se consoler en s'en jetant une au bar du coin ? :lol:


herveG
Modérateur
Modérateur
 
Messages: 9834
Inscription: Mer Mar 05, 2003 11:33

Message le Lun Jan 31, 2005 14:03

Une petite mousse pour revenir à des valeurs sures et concretes.... ;) bon courage les gars, on pense à vous !! :)

Haq
WRInaute accro
WRInaute accro
 
Messages: 2104
Inscription: Jeu Aoû 29, 2002 21:18

Re: Problème pour experts!

Message le Lun Jan 31, 2005 14:22

GAMING ZONE a écrit:Il y a un truc qui me chiffone, tu indique avoir nbachats negatifs ...


Je ne vois pas où...


GAMING ZONE
WRInaute passionné
WRInaute passionné
 
Messages: 533
Inscription: Ven Aoû 13, 2004 20:06

Re: Problème pour experts!

Message le Lun Jan 31, 2005 14:23

chameau a écrit:dans ma bd, nbachats arrive à des résultats négatif.

Didier_S
WRInaute passionné
WRInaute passionné
 
Messages: 563
Inscription: Mar Aoû 24, 2004 22:25

Message le Lun Jan 31, 2005 14:27

pourquoi tu utilises pas un peu de javascript pour éviter que les utilisateurs ne cliquent plusieurs fois rapidement ? j'ai peut-être mal compris le problème, j'avoue


Blini
WRInaute passionné
WRInaute passionné
 
Messages: 506
Inscription: Lun Nov 29, 2004 8:59

Message le Lun Jan 31, 2005 15:01

Pourquoi ne pas tout faire en une seule requête ? Ça éviterat des pbs, non ?
Code: Tout sélectionner
UPDATE utilisateur SET nbachats=nbachats+1 WHERE id='$idmembre' AND nbachats < 20

Et tu testes le retour pour voir s'il y a eu une mise à jour ou pas. Si nb_affected_rows = 0, c'est que le max a été atteint, et que l'update n'a donc rien fait.
Ça devrait repporter le pb d'accès concurrents sur la base SQL plutô que sur la page PHP...
Bon, à vérifier quand même, hein....

Erazor
WRInaute accro
WRInaute accro
 
Messages: 5166
Inscription: Sam Fév 14, 2004 10:36

Message le Lun Jan 31, 2005 15:38

Americas a écrit:on va se consoler en s'en jetant une au bar du coin ? :lol:


Code: Tout sélectionner
$query = "SELECT barducoin utilisateur WHERE id='$idpote'";
$result= mysql_query($query);
$row = mysql_fetch_row($result);
if($row[0]<20){
$nbachats=$row[0]++;
$query = "UPDATE verre SET nbachats='$nbachats' MOUSSES id='$idpote'";
$result = mysql_query($query);
//mes differentes consommations
copyleffe erazor
Language Pompe Haute Pression (PHP)

Haq
WRInaute accro
WRInaute accro
 
Messages: 2104
Inscription: Jeu Aoû 29, 2002 21:18

Message le Lun Jan 31, 2005 16:05

Blini a écrit:Pourquoi ne pas tout faire en une seule requête ? Ça éviterat des pbs, non ?
Code: Tout sélectionner
UPDATE utilisateur SET nbachats=nbachats+1 WHERE id='$idmembre' AND nbachats < 20

Et tu testes le retour pour voir s'il y a eu une mise à jour ou pas. Si nb_affected_rows = 0, c'est que le max a été atteint, et que l'update n'a donc rien fait.
Ça devrait repporter le pb d'accès concurrents sur la base SQL plutô que sur la page PHP...
Bon, à vérifier quand même, hein....


De fait, c'est de très loin la meilleure solution


MagicYoyo
WRInaute accro
WRInaute accro
 
Messages: 2529
Inscription: Lun Mai 24, 2004 15:33

Message le Lun Jan 31, 2005 16:43

A vot' santé !!


Formation recommandée sur ce thème :

Formation Google Analytics : en 2 jours, apprenez comment exploiter l'essentiel des possibilités de l'outil de mesure d'audience de Google. Formation animée par Julien Coquet, expert certifié officiellement par Google Analytics.

Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités