1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2017
    Messages : 6
    Points : 8
    Points
    8

    Par défaut Utilisation correcte ou 'moderne' de LOCK dans un logiciel ?

    * Bonjour, *

    Je suis récemment sorti du collège où j'ai appris que les LOCK sont appliqués pendant des transactions avec le RDBMS pour éviter la saisie de mauvaises données lorsque des transactions simultanées sont faites sur le même enregistrement.

    Dans le cadre de mon travail pour une firme de développement de logiciels, je dois adapter le code pour qu'on soit en mesure d'utiliser Microsoft SQL Server (le code a été développé pour rouler avec Advantage Database Server).

    Mon mandat est de faire fonctionner nos logiciels avec Microsoft SQL Server sans effectuer de modifications dans le code actuel et sans modifier le comportement des applications.

    Ma question :

    Comme je n'ai pas travaillé pour d'autres entreprises et que je n'ai jamais vu ça dans mes cours au collège, j'aimerais savoir si l'utilisation des LOCKS dans notre logiciel actuel est une pratique courante en 2017 :

    1- l'usager Alpha entre en édition dans un Mémo concernant un Projet Z.
    2- une commande est envoyée au RDBMS (Advantage) pour verrouiller le Mémo concernant le Projet Z (un lock est appliqué sur l'enregistrement 'Mémo' du 'Projet Z')
    3- Une minute plus tard, un collègue, l'usager Bêta, désire ajouter de l'information dans le Mémo du Projet Z.
    4- Notre code vérifie si l'enregistrement est verrouillé. En effet, il est verrouillé donc on ouvre un pop-up pour informer l'usager Bêta que le Mémo est déjà utilisé par l'usager Alpha et qu'il ne peut pas le modifier.

    Je comprends l'avantage de cette pratique. Mais il me semble que ce n'est pas très agréable pour les usagers ...

    (ma question est motivée par la curiosité des pratiques actuelles relatives à la gestion de LOCK sur une base de données. Mais aussi par le fait qu'il m'est difficile de verrouiller un enregistrement sur Microsoft SQL Server pour une longue durée... Pour l'instant j'ai bidouillé une solution qui ne me satisfait pas : pour verrouiller un enregistrement, j'exécute un 'Begin transaction' sans le Commiter. Je conserve la connexion verrouillée dans une map(dictionnaire) que je conserve en donnée membre dans mon Dataset et pour relâcher le LOCK j'exécute un 'Rollback' sur la transaction. À court terme, ça fonctionne mais ça ne me semble pas très orthodoxe...)

    * Merci *

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mars 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2017
    Messages : 6
    Points : 8
    Points
    8

    Par défaut réponses sur StackOverflow

    Veuillez agréer à cet ajout

    ma question sur StackOverflow :

    https://stackoverflow.com/questions/...36532_45130849


    merci beaucoup

  3. #3
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 495
    Points
    39 495
    Billets dans le blog
    1

    Par défaut

    Ce mode de fonctionnement était adapté du temps des fichiers et donc des bases non relationnelles. Avec les SGBDR ont ne procède surtout pas ainsi sinon la montée en charge va être nulle et les blocages indésirables peuvent être légion et faire crasher le système.

    En effet, prenons votre séquence et voyons quelles en sont les conséquence dans un contexte particulier qui peut survenir fréquemment :

    1- l'usager Alpha entre en édition dans un Mémo concernant un Projet Z.

    2- une commande est envoyée au RDBMS (Advantage) pour verrouiller le Mémo concernant le Projet Z (un lock est appliqué sur l'enregistrement 'Mémo' du 'Projet Z')

    3- Une minute plus tard, un collègue, l'usager Bêta, désire ajouter de l'information dans le Mémo du Projet Z.

    4- Notre code vérifie si l'enregistrement est verrouillé. En effet, il est verrouillé donc on ouvre un pop-up pour informer l'usager Bêta que le Mémo est déjà utilisé par l'usager Alpha et qu'il ne peut pas le modifier.

    5- l'usager Alpha décède, ou bien va déjeuner, ou appui sur le bouton OFF de son PC...

    6- usager Bêta, désire ajouter de l'information dans le Mémo du Projet Z. Il patiente toujours...

    7- usager Bêta, désire ajouter de l'information dans le Mémo du Projet Z. Il patiente encore....

    ...

    8365245642564524- usager Bêta, désire ajouter de l'information dans le Mémo du Projet Z. Il est mort de patience car cela fait 27543214321567 ans qu'il patiente !

    Les SGBD relationnels mettent en œuvre des verrous de manière automatique afin de ne pas devoir en poser de manuels st assurer la cohérence et la fluidité du système. Pourquoi s'en passer ? Pourquoi réinventer la roue ???

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  4. #4
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    mai 2006
    Messages
    2 554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : mai 2006
    Messages : 2 554
    Points : 4 131
    Points
    4 131

    Par défaut

    Citation Envoyé par maximebonin Voir le message
    (ma question est motivée par la curiosité des pratiques actuelles relatives à la gestion de LOCK sur une base de données. Mais aussi par le fait qu'il m'est difficile de verrouiller un enregistrement sur Microsoft SQL Server pour une longue durée... Pour l'instant j'ai bidouillé une solution qui ne me satisfait pas : pour verrouiller un enregistrement, j'exécute un 'Begin transaction' sans le Commiter. Je conserve la connexion verrouillée dans une map(dictionnaire) que je conserve en donnée membre dans mon Dataset et pour relâcher le LOCK j'exécute un 'Rollback' sur la transaction. À court terme, ça fonctionne mais ça ne me semble pas très orthodoxe...)
    C'est le moins qu'on puisse dire. En effet tu cours à la catastrophe.

    Un verrouillage applicatif est une pratique courante. si tu fais ça bien, aucun problème. La difficulté c'est toujours de gérer le plantage et les données qui restent verrouillées parce personne ne vient les libérer. Pour ça, tu peux utiliser une routine qui passe régulièrement et qui retire les verrous trop anciens. Si ton application travaille en mode connecté, tu peux utiliser le session_id comme indication de verrou pour détecter si la session est toujours ouverte, mais c'est délicat aussi à cause des pools de connexion. Il faut le faire intelligemment.

    Tu peux aussi te baser sur un mode optimiste. Tu récupères un timestamp dans l'application, et quand tu postes, tu vérifies que le timestamp est cohérent avec ce qui se trouve dans la table.
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 2 963
    Points : 4 890
    Points
    4 890
    Billets dans le blog
    1

    Par défaut

    Une autre approche serait de ne rien verrouiller dans l'application.

    Mais au moment d'enregistrer la modification, faire une vérifications que les données en cours de modification n'ont pas été modifiées entre temps par une autre personne.
    => Simplement indiquer à ce moment à l'utilisateur qu'il va écraser les données d'une autre personne. Proposer éventuellement un écran qui indique ce qui a été changé par l'autre personne pour pouvoir arbitrer.

    J'ai longtemps travaillé sur un ERP qui utilisait un système de lock merdique comme celui que vous décrivez.
    Outre les perfs catastrophiques, à chaque fois qu'une personne modifiait un produit (pour ajouter un nouveau numéro de lot par exemple, saisir des tarifs pour la période à venir, etc.) alors l'ensemble des transactions sur les commandes, livraisons et factures étaient bloquées.

    Quand y'a 10 camions qui restent bloqués au dépôt car Ginette est partie déjeuner sans fermer la fiche produit, c'est des milliers d'euros qui sont perdus.
    Alors que 99% du temps (pour ne pas dire 99,99999999999999999% du temps) l'utilisateur qui verrouille un enregistrement ne va pas modifier d'informations susceptibles d'être modifiées par une autre personne (chacun son métier, chacun son portefeuille de clients, commandes, produits, etc.)

    Il est très rare que deux personnes veuillent saisir des tarifs en même temps sur un même produit : sinon c'est qu'il y a une très mauvaise organisation.
    Et quand bien même : vu que les deux personnes vont (en toute logique, sinon il y a vraiment un très un gros problème) soit saisir les mêmes informations de manière identique, soit saisir des informations différentes et complémentaires, il n'y a aucune utilité à verrouiller quoi que ce soit.
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    mai 2006
    Messages
    2 554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : mai 2006
    Messages : 2 554
    Points : 4 131
    Points
    4 131

    Par défaut

    Tu as raison StringBuilder, c'est plus raisonnable qu'un verrouillage pessimiste. Il y a un exemple de ce type d'approche, et c'est pour cela que je parlais d'un timestamp, c'est la façon dont CouchDB gère la mise à jour, en testant un ID de révision.
    http://couchdb.developpez.com/tutori...ction/#LIV-C-1

    On peut le faire à la main dans SQL Server, par exemple avec un GUID.
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  7. #7
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 2 963
    Points : 4 890
    Points
    4 890
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par rudib Voir le message
    On peut le faire à la main dans SQL Server, par exemple avec un GUID.
    Ou avec une colonne de type timestamp, qui sert justement exactement à ça (et n'est pas un timestamp au sens Linux) :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    create table TimeStampedTable
    (
    	id int identity primary key,
    	valeur varchar(10) not null,
    	[version] timestamp
    );
    go
     
    insert into TimeStampedTable (valeur) values ('Toto'), ('Titi'), ('Tata');
     
    select * from TimeStampedTable;
    1 Toto 0x00000000000007D5
    2 Titi 0x00000000000007D6
    3 Tata 0x00000000000007D7
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update TimeStampedTable set valeur = 'Lulu' where id = 2;
     
    select * from TimeStampedTable;
    1 Toto 0x00000000000007D5
    2 Lulu 0x00000000000007D8
    3 Tata 0x00000000000007D7
    L'avantage du timestamp c'est qu'il est totalement automatique, pas la peine de rajouter des triggers ou modifier les requêtes pour la modifier à chaque modification des lignes.
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 495
    Points
    39 495
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par StringBuilder Voir le message
    Ou avec une colonne de type timestamp
    ATTENTION : timestamp est sémantiquement obsolète depuis la version 2005. Il faut utiliser un type ROWVERSION !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  9. #9
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 495
    Points
    39 495
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par StringBuilder Voir le message

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    update TimeStampedTable set valeur = 'Lulu' where id = 2;
     
    select * from TimeStampedTable;
    Le principe dans ce cas est de faire la requête de MAJ suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    update TimeStampedTable 
    set valeur = 'Lulu' 
    where id = 2 
    AND version = @version; --> valeur lue au démarrage du processus de MAJ par l'IHM
    IF @ROWCOUNT = 0
       ... --> traitement en cas de perte de MAJ
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  10. #10
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    mai 2006
    Messages
    2 554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : mai 2006
    Messages : 2 554
    Points : 4 131
    Points
    4 131

    Par défaut

    J'ajoute encore un petit caillou à l'édifice, utiliser une séquence (SQL Server 2012). Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE SEQUENCE dbo.stamp
    AS INT
    START WITH 1
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 2147483647
    CYCLE;
     
    UPDATE matable
    SET stamp = NEXT VALUE FOR dbo.stamp
    OUTPUT inserted.stamp
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  11. #11
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 495
    Points
    39 495
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par rudib Voir le message
    J'ajoute encore un petit caillou à l'édifice, utiliser une séquence (SQL Server 2012).
    Ha oui, celle-là elle est pas mal car elle permet de numéroter le versionnement de manière unitaire éventuellement pour chaque ligne en créant autant de séquenceurs et en utilisant un déclencheur.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

Discussions similaires

  1. Réponses: 30
    Dernier message: 05/12/2013, 17h48
  2. comment utiliser les lock dans les threads ?
    Par skad dans le forum Général Python
    Réponses: 2
    Dernier message: 15/07/2008, 14h28
  3. [Applet]utiliser une classe d'un package dans une applet
    Par jeromejanson dans le forum Applets
    Réponses: 1
    Dernier message: 30/06/2005, 08h13
  4. TAO , lock dans ORB_init au lancelent du serveur
    Par franck_92 dans le forum CORBA
    Réponses: 1
    Dernier message: 23/12/2004, 11h02
  5. pb d'utilisation du resultat d'1 requete dans 1 autre
    Par joquetino dans le forum Langage SQL
    Réponses: 7
    Dernier message: 09/03/2004, 15h58

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