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

MS SQL Server Discussion :

Accès concurrents, verrous, oui mais


Sujet :

MS SQL Server

  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Septembre 2007
    Messages : 41
    Points : 38
    Points
    38
    Par défaut Accès concurrents, verrous, oui mais
    Bonjour communauté,
    J'ai un soft sous réseau local, Voici les tables concernés par le problème :

    1. Table "Client"
    2. Table "Enfant"

    Donc un client à plusieurs enfants (cardinalité 1,n) et un enfant n'est relié qu'a un seul client (1,1).

    Le scénario qui me pose problème est le suivant :
    a- Un utilisateur dans un PC1, ouvre le dossier du client "Dubois", et met a jour sa fiche client,
    b- au même moment, un autre utilisateur dans un PC2, ouvre la même fiche et met a jour la liste des enfants.
    c- l'utilisateur PC1 enregistre les données (ça affecte que la table client)
    d- l'utilisateur PC2 enregistre les données (ça affecte les deux tables). Etant donné que la fiche a été ouverte avant la mise à jour des données, et qu'en enregistrant les données, le PC2 va envoyer les anciennes informations (de la table client) qui sont justement affiché sur sa fiche.

    Je me demande donc, vous qui êtes surement passé par là, comment résoudre ce problème ?

  2. #2
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Une solution :

    J'implémenterais un flag sous forme d'une colonne "flag" avec un type BIT par exemple sur votre table client :

    - PC1 ouvre la fiche client --> mise à jour colonne "flag" à 1 par exemple
    - PC2 ouvre la même fiche client --> si "flag" = 1 alors fiche verrouillée

    ++

  3. #3
    Nouveau membre du Club
    Inscrit en
    Septembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Septembre 2007
    Messages : 41
    Points : 38
    Points
    38
    Par défaut
    Cela me semble intéressant comme idée.
    Mais je me demande, quand est ce que le flag passe a 0, pour dire que la table est à jour. et dans le cas ou par exemple le PC1 bug, le flag restera sur 1. Comment gérer ça ?
    Merci mikedavem

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 917
    Points : 51 693
    Points
    51 693
    Billets dans le blog
    6
    Par défaut
    Vous vous trompez dans votre scénario car rien n'est mis à jour par l'utilisateur 2 dans la table client

    D'autre part vous raisonnez en terme d'IHM et non en terme de bases de données et transactions. Si vous voulez que la mise à jour d'un ensemble de données père/fils soit monolithique il faut gérer une transaction. Maintenant soit vous la gérez en mode optimiste (verrouillage à postériori) ou bien en mode pessimiste (verrouillage à priori). Pour la montée en charge le verrouillage à priori (donc pessimiste) est catastrophique....

    En fait vous ne vous posez pas la bonne question : quel est l'intérêt de "bloquer" la vision d'une information, et quelle est la règle pour considérer que tel ou tel utilisateur doit "gagner"...
    Par exemple vous avez considéré que c'était le premier à modifier qui devait gagner dans votre exemple. Mais si le 2e est le PDG de la boîte, ne devrait -il pas écraser le premier ?
    Vous comprenez que raisonner de cette manière n'a en fait aucun sens, sauf à définir quels traitements provenant de quels personnes doivent passer en priorité à tout autre...
    Cela ne vous choque pas de voir un livre sur fnac.com, puis après avoir hésitez à l'acheter et alors qu'il était en stock, constater que votre achat sera plus long que prévu car quelqu'un d'autre entre temps à acheter le seul exemplaire qui était en stock. Et heureusement !

    L'extrême danger avec un flag (solution de Mikedavem) est que souvent l'utilisateur va oublier de finaliser ou encore va passer une heure entre le début et la confirmation, parce que entre temps le téléphone à sonné. Votre base deviendra vite impossible à utiliser et vous devrez faire le pompier pour réparer les flags intempestivement placé à 1.
    En fait ce n'est jamais comme cela que l'on travaille les bases de données de type C/S... !

    A +

  5. #5
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Effectivement la solution que je propose a un gros inconvénient que SQLPro vient de citer.

    J'ai vu ce genre de choses implémentées sur des logiciels de gestion qui permettait de verrouiller "en écriture" la mise à jour d'une intervention par exemple où une 1ère personne pouvait modifier l'intervention et les suivantes ne pouvaient avoir qu'une consultation en lecture.

    Effectivement lors de plantage, l'action de déverrouiller l'intervention en écriture était du ressort de l'administrateur de l'application.

    Juste par curiosité SQLPro (ou autres personnes) comment gérerais tu ce genre de cas ? (classique dans les logiciels de gestion d'incidents)

    - Utilisateur 1 ouvre une fiche d'intervention.
    - Utilisateur 2 ouvre la même fiche d'intervention mais je veux que seul le 1er utilisateur puisse modifier les informations de cette intervention mais je ne veux pas pour autant bloquer les autres utilisateurs en consultation...

    ++

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 917
    Points : 51 693
    Points
    51 693
    Billets dans le blog
    6
    Par défaut
    Il n'y a aucune autre solution que de définir un "time out" pour le relâchement du verrous. Ainsi le verrou n'est pas un bit mais un timestamp (date + heure) et s'il est trop vieux alors il est automatiquement dégagé par un bacth de fond qui parcoure les lignes toutes les n secondes pour nettoyer les verrous les plus anciens. Sur certains site (TGV.com ?) je crois que c'est 2 minutes.

    Sinon une autre façon est de tagger la ligne et de n'autoriser la modification que si le tag est le même en entrée et sortie.
    Exemple : une colonne GUID est rajoutée à la table maître. Lorsque je lit les données je capture ce GUID. Lorsque je met à jour j'ajoute à l'update le fait que le GUID de la ligne doit être égal au GUID que j'ai capturé et je remet à jour en même temps ce GUID avec une nouvelle valeur (automatiquement avec ROWVERSION). Si la valeur est différente, l'UPDATE ne se fait pas....

    Cela ne verouille pas intempestivement mais assure la cohérence d'entrée sortie de la mise à jour.

    Mais entre nous tout ce genre de chose c'est de la bidouille qui plombe les perf..... Mieux vaut laisser le SGBDR comme il se doit, le risque de télescopage étant d'autant plus faible qu'il y a beaucoup de données !

    PS : je suis en train d'écrire depuis Redmond USA ou je suis en séminaire MVP chez Microsoft ! Je m'emmerde avec Azure...

    A +

  7. #7
    Nouveau membre du Club
    Inscrit en
    Septembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Septembre 2007
    Messages : 41
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Vous vous trompez dans votre scénario car rien n'est mis à jour par l'utilisateur 2 dans la table client

    D'autre part vous raisonnez en terme d'IHM et non en terme de bases de données et transactions. Si vous voulez que la mise à jour d'un ensemble de données père/fils soit monolithique il faut gérer une transaction. Maintenant soit vous la gérez en mode optimiste (verrouillage à postériori) ou bien en mode pessimiste (verrouillage à priori). Pour la montée en charge le verrouillage à priori (donc pessimiste) est catastrophique....
    A +
    Merci pour les précisions, je suis enchanté que vous soyez tout a fait sur la même longueur d'ondes que moi, respect.

    Vous conseillez de laisser le SGBD gérer le problème, ma question est la suivante :
    Dans le cas où un utilisateur ouvre une une fiche contenant les données d'une table X (client par exemple), et qu'un autre utilisateur ouvre la même fiche du même client. Le premier utilisateur ayant un droit inférieur au deuxième (par exemple un secrétaire et un responsable RH). Dans ce cas là, comment est-ce que je peux donner la priorité au Responsable ? Au niveau application, ou au niveau BDD ??

    Et si le réponsable enregistre sa fiche après avoir modifié des informations sur le client, le secrétaire tente d'enregistrer après la fin de la transaction. Comment dans ce cas là, définir ou tester si la version des données est plus récentes ou non ? donc si c'est pas le cas, ne pas mettre à jour du tout, et si c'est le cas, lancer la transaction normalement.

    Je ne suis pas amateur, ni professionnel, j'essaye juste de raisonner en tant qu'informaticien, et ce problème là... me casse la tête

    Merci à vous deux

  8. #8
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    >> SQLPro

    Après avoir regardé chez un ancien client effectivement ils opérent par suppression des verrous en fonction d'un critère de temps.

    Bon tu es aux states et tu vois Azure c'est bien non

    >> AkqiraDev
    Pourquoi vouloir donner une priorité à une personne ?
    Admettons que vous vouliez le faire pour un responsable et un subordonné ...
    Comment savoir que les informations entrées par le responsable sont toujours prioritaires par rapport à son subordonné ?

    ++

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 917
    Points : 51 693
    Points
    51 693
    Billets dans le blog
    6
    Par défaut
    Je ne suis pas amateur, ni professionnel, j'essaye juste de raisonner en tant qu'informaticien, et ce problème là... me casse la tête
    Laissez agir le système... Ce sera plus sûr !
    Vos clients ont-il exigé ceci contractuellement ? si oui, alors c'est du fonctionnel, si non alors inutile de vous prendre le chou !

    A +

  10. #10
    Nouveau membre du Club
    Inscrit en
    Septembre 2007
    Messages
    41
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Septembre 2007
    Messages : 41
    Points : 38
    Points
    38
    Par défaut
    Bonjour a tous,
    Merci pour vos commentaires et vôtre partage d'expérience.
    Je viens de lire un article qui se trouve ici.

    Il est interessant et répond à mon problème, l'article est en anglais, et pour ceux qui veulent un résumé voici la solution proposé par l'auteur :
    En utilisant le type "timestamp" ou ce qu'on appelle aussi le "RowVersion".
    C'est une colonne qui change de valeur automatiquement a chaque modification du contenu de sa ligne.
    Donc au lieu de mettre une colonne verrou et de balayer chaque x temps, je mets une colonne RowVersion et au moment de lire les données de la ligne, je ramène la valeur de cette colonne, et juste avant de mettre a jour ma ligne, je teste si la valeur actuelle correspond à la valeur que j'ai déjà retiré.

    Voila, si vous avez des remarques sur ça, allez y.

    Et bon courage pour Azure

Discussions similaires

  1. Réponses: 5
    Dernier message: 16/10/2008, 19h14
  2. acces concurrent avec delphi 5 entreprise
    Par Jean_paul dans le forum Bases de données
    Réponses: 2
    Dernier message: 30/11/2004, 20h19
  3. HomeDB, oui mais comment ?
    Par Gregouz dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 27/10/2004, 15h27
  4. [APPLET-SERVLET] download oui mais upload non ...
    Par meufeu dans le forum Applets
    Réponses: 7
    Dernier message: 09/08/2004, 14h36
  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