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 :

Requête effectuée au même moment par 2 utilisateurs


Sujet :

PHP & Base de données

  1. #1
    Membre du Club
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 62
    Points
    62
    Par défaut Requête effectuée au même moment par 2 utilisateurs
    Bonjour,

    Je tourne en rond depuis 4 jours sur une problématique que je n'arrive pas à résoudre.

    Je publie un évènement sur mon site Web pour lequel des utilisateurs peuvent s'inscrire.

    - Dans mon cas, j'ai besoin de 2 utilisateurs seulement.
    - Le site gère seul le fait que les 2 premiers inscrits auront le statut "accepté" d'office (premier arrivé : premier servi).
    - 2 autres utilisateurs peuvent s'inscrire mais auront le statut "sur file d'attente".


    Le problème :
    - J'ai donc un premier utilisateur qui s'inscrit à 13h57, statut "accepté".
    - J'ai ensuite l'inscription de 2 utilisateurs simultanés, à 14h01 (et 13 secondes exactement). Les deux obtiennent le statut "accepté" d'office alors que l'un d'eux aurait dû être sur file d'attente.
    Les requêtes de vérification ayant lieu à la même seconde, tout était correct à ce moment précis...
    Mais voilà, j'ai 3 personnes dont le statut est "accepté" au lieu de 2...


    Je précise que le système a toujours bien fonctionné jusque là, donc pour moi, aucun problème de code, tout a été vérifié. Sauf que là, c'est un cas bien particulier.

    Auriez-vous une idée qui expliquerait cela?
    Merci d'avance.
    "Les tests sont au développement ce que le fromage est à la fondue"

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur C++
    Inscrit en
    Avril 2012
    Messages
    771
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur C++
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2012
    Messages : 771
    Points : 1 631
    Points
    1 631
    Par défaut
    Bonjour,

    comment gère tu la vérification du nombre d'utilisateur étant accépté ?

    De manière applicative ou une contrainte dans le SGBDR ?
    une réponse vous a permis d'avancer ?

  3. #3
    Membre du Club
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 62
    Points
    62
    Par défaut
    Bonjour,

    Voici comment ça se passe d'un point de vue algo :
    Dans ma table "évènement", j'ai un champs "statut_evt" qui définit quel statut les personnes auront à l'inscription (ce champs peut paraître inutile, mais j'en ai besoin).
    Donc à la création d'un évènement, le statut par défaut est "accepté" :
    statut_evt = accepte;

    Tant que je n'ai pas atteint mon quota, ce statut ne change pas.

    Quand une personne s'inscrit, je vérifie "statut_evt" et ensuite, je vérifie si son inscription atteindra le quota. Si c'est le cas, je change le statut de l'évènement :
    "statut_evt" = "file d'attente",
    puis j'inscrit mon utilisateur qui aura le statut "accepté".

    Donc le prochain utilisateur aura le statut "file d'attente" (selon le champs de ma table "évènement" : "statut_evt").

    Je ne sais pas si j'ai été assez claire...
    "Les tests sont au développement ce que le fromage est à la fondue"

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Quand une personne s'inscrit, je vérifie "statut_evt"
    Par une requête ?

    ensuite, je vérifie si son inscription atteindra le quota.
    Par une autre requête ?

    Si c'est le cas, je change le statut de l'évènement :
    "statut_evt" = "file d'attente",
    Donc une autre requête !

    j'inscrit mon utilisateur qui aura le statut "accepté".
    Et encore une requête.

    Entre temps, un autre utilisateur est venu s'inscrire avant que la requête de changement de statut n'ait eu lieu.

    Tu devrais passer par une procédure SQL qui permettra de faire toutes les opérations en une seule transaction et en verrouillant les tables et le second utilisateur attendra que la première inscription soit terminée. Rassure-toi, ça va très vite et l'utilisateur physique derrière son écran ne sentira pas la différence.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Membre du Club
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 62
    Points
    62
    Par défaut
    Merci CinePhil pour cette réponse, c'est un peu près ça à une requête près.
    Je pense faire ça avec une transaction géré en PHP, car j'ai pas mal de condition intercalé entre mes différentes requêtes.
    Est-ce que ça fonctionnera? (je n'ai jamais fait de transaction dans ma vie de développeur)
    "Les tests sont au développement ce que le fromage est à la fondue"

  6. #6
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    salut,

    la procédure stockée va te permettre d'encapsuler en elle toute la logique de décision et les requêtes, ça évite les allers-retours php/mysql et c'est plus facile à maintenir

    les transactions ça n'a de sens qu'avec des tables en innodb sinon tu devras faire des lock/unlock mais eux sont sur une table entière... après il y a plusieurs niveau d'isolation dans les transactions, faut voir celui qui convient le mieux et ça dépend de comment tu gères justement le suivi... tu écriras des transaction plus efficacement dans une procédure et ça limitera beaucoup les risques de blocage de tables...

    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

  7. #7
    Membre éprouvé Avatar de redoran
    Homme Profil pro
    Développeur-Amateur
    Inscrit en
    Juin 2010
    Messages
    1 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur-Amateur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 346
    Points : 1 031
    Points
    1 031
    Par défaut
    Salut ; + de ce qui est dit et pour plus d’équité le tous ce joue sur le temps d'inscription soit pour statut accepter ou liste d'attente.

  8. #8
    Membre du Club
    Femme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Points : 62
    Points
    62
    Par défaut
    Merci à tous pour vos réponses, j'y vois un peu plus claire dorénavant.
    Je ne savais pas quoi utiliser entre les procédures stockées ou les transactions.

    Je me suis donc lancée dans les transactions avec l'isolation sur "serializable".
    D'après ce que j'ai compris, il verrouille uniquement les lignes concernées (dites moi si je me trompe). Donc pas de lock/unlock sur les tables entières.

    Par contre, je n'arrive même pas à reproduire le bug de base à l'aide de requête ajax asynchrone...
    Si je rajoute les transactions, je vois bien le comportement attendu dans les logs mysql mais, je ne vais pas pouvoir vérifier que le bug ne se reproduira plus...
    "Les tests sont au développement ce que le fromage est à la fondue"

  9. #9
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    c'est ça...

    serializable est en effet ce qui est le mieux pour ce que tu veux faire je pense

    mais l'idéal est d'utiliser les 2 biensur, procédure et transaction... en plus tu peux faire un gestionnaire d'erreur qui va juste faire un rollback au lieu de générer l'erreur et faire un rollback (un peu comme un try ... catch) genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    declare continue handler for sqlexception rollback;
    tu peux aussi mettre un bloc de code, encadré par dans le handler pour faire des actions plus compliquées genre la gestion d'un log d'erreur, etc...
    soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...
    ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...

Discussions similaires

  1. Réponses: 4
    Dernier message: 07/07/2008, 16h43
  2. Réponses: 2
    Dernier message: 05/07/2007, 21h11
  3. requête access (test d'une valeur entrée par l'utilisateur)
    Par ben5985 dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 30/11/2006, 08h39
  4. Réponses: 6
    Dernier message: 11/09/2006, 12h58
  5. Réponses: 44
    Dernier message: 14/03/2005, 09h43

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