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

 MySQL Discussion :

Transaction et accès concurrent


Sujet :

MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    amateur
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Par défaut Transaction et accès concurrent
    Bonjour,

    j'ai un petit souci concernant les transactions mysql, voici un exemple :

    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
    try
    		{
    			$bdd->beginTransaction();
     
    			$req = $bdd->prepare('SELECT champ FROM table WHERE id=1');
    			$req->execute();
                            $res = $req->fetch();
     
                            $req = $bdd->prepare('UPDATE table SET champ=? WHERE id=1');
    			$req->execute(array($res['champ']+1));
     
    			$bdd->commit();
    		}
    		catch (Exception $e)
    		{
    			$bdd->rollback();
    			throw new Exception('...');
    		}
    (c'est un exemple pour illustrer ma question, pas un code que j'utilise !)

    Si 2 utilisateurs accèdent en même temps à ce code que se passe-t-il ?

    J'ai beau lire et relire la doc ainsi que des dizaines de topic qui abordent plus ou moins ce sujet la réponse n'est pas claire dans ma tête...Un coup je lis que les transactions vont s’exécuter les unes à la suite des autres, un coup l'inverse mais qu'il y a un lock implicite sur les données manipulées, bref je sais plus à quoi m'en tenir.

    merci d'avance

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Cela dépend du mode d'isolation des transactions.

    Globalement, les transactions vont démarrer en même temps.
    1/ Si votre mode d’isolation est bas (READ UNCOMMITED), les deux transactions s’effectueront en parallèle, sans blocage.
    2/ En READ COMMITED et REPEATABLE READ, les deux transactions effectueront le SELECT, et l'une des deux sera bloquée au moment de l'UPDATE tant que l'autre ne sera pas validée.
    3/ En SERIALIZABLE, les deux transactions effectueront le SELECT, posant chacune un verrou. Ainsi, aucune des deux transactions ne pourra faire l'UPDATE, et les deux transactions s’interloqueront : l'une sera automatiquement annulée (avec une erreur), l'autre pourra alors terminer et être validée.

  3. #3
    Candidat au Club
    Homme Profil pro
    amateur
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Par défaut
    Merci,

    innodb étant en REPEATABLE READ par défaut je sais à quoi m'en tenir

    donc si je veux que l'incrémentation se fasse bien 2 fois (+1+1 donc +2) il me faut poser un verrou au moment du select pour que la 2nd transaction soit mise en attente quand elle veut faire le select, c'est bien ça ?

    c'est le but du SELECT...FOR UPDATE il me semble d'après mes recherches ?

    y a-t-il une autre solution ? (mis à part faire ça en une requête, c'est pour l'exemple et la compréhension du mécanisme)

    il me semble avoir lu aussi qu'un SELECT...FOR UPDATE pose un verrou lecture/ecriture mais que ce verrou n'est pas pris en compte si je fais un simple SELECT derrière dans une autre transaction, ça impose que je mette des SELECT...FOR UPDATE partout ? ça me semble très lourd

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Il faudrait savoir plus précisément ce que vous voulez faire pour une réponse plus précise.

    En effet,dans votre exemple, comme vous l'avez indiqué, il suffit de faire une requête UPDATE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    UPDATE table
    SET champ = champ + 1
    Par ailleurs, il est déconseillé de gérer les transactions dans votre code applicatif : les allers/retours réseaux augmentent la durée des transaction, et donc la durée de pose des verrous...
    Il serait donc préférable de créer des procédures stockées pour faire tout ça.

    Dans le cas exposé, le FOR UPDATE serait en effet une solution, et il n'est pas forcément nécessaire de le mettre partout où la table est utilisée. Tout dépend du contexte des autres processus... il faut donc avoir une vue d'ensemble de tous vos processus pour gérer correctement cette problématique.

    Le mieux est encore de faire des tests, ce que vous pouvez faire en ouvrant deux connexions.

  5. #5
    Candidat au Club
    Homme Profil pro
    amateur
    Inscrit en
    Mai 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 3
    Par défaut
    Je n'ai pas de but concret pour le coup, j'ai volontairement créé un exemple tordu pour comprendre la chose avant d'y être confronté un jour ou l'autre !

    Ok pour le FOR UPDATE c'est bien ce qu'il me semblait.

    Concernant les transactions dans le code applicatif je dois dire que c'est la première fois que j'entends ça mais ça me semble tout à fait logique en effet (sous réserve que le serveur sql ne soit pas sur la même machine que le serveur qui exécute le code, je me trompe ? ou alors dans une moindre mesure)

    Cependant je n'en suis pas encore la point de vue optimisation mais je garde ça derrière l'oreille sans faute c'est très intéressant.

    J'en étais arrivé à la même conclusion concernant les tests, je ne m'en priverai pas !

    merci en tout cas

Discussions similaires

  1. [Data] LAST_INSERT_ID() Transaction Spring Accès Concurrent
    Par w3blogfr dans le forum Spring
    Réponses: 0
    Dernier message: 03/11/2010, 12h06
  2. [QtSql] QtSql et transaction, accès concurrent
    Par Nico_tournai dans le forum PyQt
    Réponses: 8
    Dernier message: 23/08/2010, 17h45
  3. Réponses: 5
    Dernier message: 16/10/2008, 19h14
  4. [EJB2] Problème accès concurrents/transaction
    Par Gevaudan35 dans le forum Java EE
    Réponses: 3
    Dernier message: 18/10/2006, 19h22
  5. [EJB] Accès concurrents à la base de données
    Par cameleon2002 dans le forum Java EE
    Réponses: 10
    Dernier message: 23/09/2003, 11h31

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