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 bloquante en MySQL (transactions?) [MySQL]


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut Requête bloquante en MySQL (transactions?)
    Bonjour,

    J'ai lu pas mal de threads ici et ailleurs, mais je ne suis pas convaincu que ce que compte faire est correct.

    Mon problème est simple. Je veux récupérer les enregistrements qui ne sont pas notés comme "traités" puis les noter comme traités.

    Il y a bien sûr un problème de concurrence, pour ne pas donner des enregistrements non traités à deux clients différents.

    mon idée de base est

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mysqli_query("start transaction");
    mysqli_query("select ... from ... where `processed` = 0");
    // Traitement des données du select
    mysqli_query("update set `processed` = 1 where `processed` = 0");
    mysqli_query("commit");
    Est-ce que cette façon de faire est correcte? Surtout, est-ce qu'elle me garanti que deux clients ne recevront pas les mêmes enregistrements?

    Je n'ai jamais travaillé avec de la concurrence en base de données et je ne suis pas très sûr que c'est cela fonctionne ainsi.

    merci de votre aide

    edit: modification du code pour meilleure compréhension

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Le SELECT avant l'UPDATE n'a aucun effet.
    Il n'y a de toute facon pas de concurrence dans ton cas : ta ligne à un moment donné vaut soit 0 soit 1.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE table SET client='toto', processed= 1 WHERE processed=0;
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    Si je fais un select, c'est parce que je veux connaitre les elements qui ne sont pas processed !

    Mon probleme est que si deux processus différents s'executent


    process1: select...
    process2: select...
    process1: update...
    process2: update...
    process1: traitement des données
    process2: traitement des données

    Dans ce cas les données seront traitées deux fois, c'est justement ce que je veux éviter!
    Ou alors j'ai mal compris ce que tu as dit?

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Peut être voir du coté de LOCK TABLES / UNLOCK TABLES que les transactions.

    Ceci dit, et si je ne dis pas de bêtise, une transaction c'est fait justement pour éviter la concurrence, ça revient au même que de bloquer les tables.
    Donc normalement il n'y a pas besoin de t'appuyer sur une donnée de la Bdd comme ton champ processed.
    En fait, on dirait que tu es en train de créer toi même ton propre système de processus.

    Si tu as une succession de SQL à faire et qu'ils ne doivent pas être perturbés, tu les regroupe dans 1 transaction, cela va verrouiller les tables concernées, il y aura une file d'attente si un autre processus tente d'interroger les mêmes tables.
    Enfin, c'est ce que j'ai retenu des transactions.


    Le scénario que tu a mis est théoriquement impossible, le processus2 (plutôt transaction) attendra que le le 1er finisse.

    Enfin, si j'ai bien compris ton problème.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    Merci pour ta réponse.

    Mon champ "processed" a d'autres utilités dans le code, il n'est pas là uniquement pour effectuer un blocage.

    Tu m'embrouilles un peu là, il vaut mieux utiliser LOCK TABLES ou les transactions, puisqu'apparemment cela fait la même chose?

  6. #6
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Tu m'embrouilles un peu là, il vaut mieux utiliser LOCK TABLES ou les transactions, puisqu'apparemment cela fait la même chose?
    Désolé pour l'embrouille

    Ca dépend du moteur de MySQL que tu utilise.
    Tu ne pourras pas faire de transaction avec le moteur MyISAM, utiliser les LOCK TABLES deviens la seule manière d'éviter la concurrence, cela simule une transaction.

    Si tu veux utiliser les transactions (commit / rollback), faut utiliser le moteur InnoDB.


    Attention cependant concernant les hébergeurs mutualisés, car même s'ils autorisent l'utilisation de InnoDB, certains ne peuvent pas garantir une sauvegarde complètes de la Bdd.
    Ca peut avoir son importance.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    J'utilise InnoDB.

    Je peux donc faire une transaction comme expliqué dans mon premier post sans avoir de problèmes?

  8. #8
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Citation Envoyé par NeqO55 Voir le message
    Je peux donc faire une transaction comme expliqué dans mon premier post sans avoir de problèmes?
    Normalement oui.

    Il te faut quand même bien implanter ton code de façon que s'il y a erreur pendant le traitement, derrière il y aura un rollback, sinon ???

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    Ok, je vais voir ça.

    merci beaucoup !

  10. #10
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    J'insiste mais ce que tu fais ne sert a rien
    si tu fais WHERE processed=0 tu ne traiteras que les lignes que tu veux.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    Oui mais il faut bien que je garde une trace des éléments qui ont déjà été traités, non ?

    Sans parler de concurrence, imagine qu'un process est relancé 3 jours après. Je ne veux pas que ces éléments soient traités, puisqu'ils ont étés traités 3 jours plus tôt.

    Chaque élément doit être traité une et une seule fois, à vie.

    J'ai sûrement mal compris ce que vous essayez de me faire comprendre :/

  12. #12
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Reprend la requête que je t'ai fourni au début : elle traite les lignes et indique qu'elles ont été traitées.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2006
    Messages : 45
    Par défaut
    Moi je veux connaitre le contenu de ces lignes.
    La méthode UPDATE ne permet pas de connaitre le contenu, juste de le modifier, non ?

  14. #14
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Hum ... tu peux alors
    1 - mettre tes lignes "en cours de traitement"
    2 - faire le SELECT sur ce statut
    3 - réaliser le traitement
    4 - mettre les lignes traitées en "traitées"

    Pour moi la transaction n'apporte rien en tout cas : l'idée de la transaction c'est "tout le traitement est réalisé ou sinon on annule".
    La gestion des Locks est possible, mais en php ce n'est pas forcemment evident non plus.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Exécution d'une requête sans stocker les transactions
    Par Actarus69 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 24/03/2006, 12h45
  2. Convertir une requête Acces en MySQL
    Par Creepy78 dans le forum Langage SQL
    Réponses: 10
    Dernier message: 28/02/2006, 16h24
  3. Requête hyerarchique avec MySQL
    Par ingamo dans le forum Requêtes
    Réponses: 3
    Dernier message: 09/02/2006, 21h39
  4. Requête sur DB mysql
    Par Lord_FEFF dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 09/11/2005, 19h16
  5. Convertir une requête Access en MySQL
    Par iomega dans le forum Langage SQL
    Réponses: 5
    Dernier message: 06/03/2004, 09h47

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