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 :

Gestion des verrous


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 181
    Par défaut Gestion des verrous
    Bonjour,
    Dans le cadre de mon projet, je dois garantir que les données ne soient modifiées que par un seul utilisateur à la fois. Plus précisément, il s'agit d'empêcher l'accès à une ligne si un utilisateur la déjà sélectionnée.
    Je pense donc utiliser le mécanisme des verrous:
    - De quelle manière puis-je m'y prendre
    - Suis-je sur la bonne voie?
    - Est-ce que seule la base de données doit gérer cela?

    Merci par avance pour vos réponses.

    PS : Des liens vers des tutoriels seraient le top

    Cordialement,
    Daniel

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Vous pouvez laisser faire SQL Server, il sait très bien faire cela.

    Vous pouvez aussi ajouter une colonne à votre table et la mettre à jour à chaque fois qu'un utilisateur demande à la modifier, et ne remonter aux autres utilisateurs que les lignes pour lesquelles cette colonne n'est pas en cours de mise à jour ...

    @++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 181
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Bonjour,

    Vous pouvez laisser faire SQL Server, il sait très bien faire cela.

    Vous pouvez aussi ajouter une colonne à votre table et la mettre à jour à chaque fois qu'un utilisateur demande à la modifier, et ne remonter aux autres utilisateurs que les lignes pour lesquelles cette colonne n'est pas en cours de mise à jour ...

    @++
    Peux-tu être plus précis sur la méthode à employer?

    Merci par avance

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Je vais tenter

    Supposons que vous faites partie d'une équipe de tests informatique.
    Chacun des membres de votre équipe peut réaliser un seul test à la fois.

    Au départ, vous avez donc l'architecture suivante :

    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
    SET NOCOUNT ON
    GO
     
    CREATE TABLE TEST
    (
    	IDTest INT IDENTITY CONSTRAINT PK_TEST PRIMARY KEY,
    	nomTest VARCHAR(16)
    )
    GO
     
    INSERT INTO dbo.TEST VALUES ('INTEGRATION')
    INSERT INTO dbo.TEST VALUES ('UNITAIRE')
    INSERT INTO dbo.TEST VALUES ('FONCTIONNEL')
    INSERT INTO dbo.TEST VALUES ('RECETTE')
    INSERT INTO dbo.TEST VALUES ('NON-REGRESSION')
    GO
    Mais comme votre équipe est très efficace, vous enchaînez les tests et il arrive parfois que vous fassiez parfois le même test, donc un travail en double.
    Pour pallier à ce problème, vous décidez donc d'ajouter une identification au logiciel de tests, qui vous permettra de n'affecter un test qu'à un seul membre de votre équipe :

    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
    CREATE TABLE TESTEUR
    (
    	IDTesteur INT IDENTITY CONSTRAINT PK_TESTEUR PRIMARY KEY,
    	prenomTesteur VARCHAR(20) NOT NULL,
    	nomTesteur VARCHAR(20) NOT NULL,
    	CONSTRAINT UQ_TESTEUR UNIQUE (prenomTesteur, nomTesteur)
    )
    GO
     
    INSERT INTO dbo.TESTEUR VALUES ('El', 'SUKET')
    INSERT INTO dbo.TESTEUR VALUES ('Dana', 'X')
    INSERT INTO dbo.TESTEUR VALUES ('Barbara', 'ZEDPRAI')
    INSERT INTO dbo.TESTEUR VALUES ('Tatiana', 'TATIENAPAS')
    INSERT INTO dbo.TESTEUR VALUES ('Camille', 'HONNETE')
    GO
    Puis vous modifiez la table TEST :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE TEST
    ADD IDTesteur INT NULL CONSTRAINT FK_TEST_IDTesteur FOREIGN KEY (IDTesteur) REFERENCES dbo.TEST
    Ainsi donc vous pouvez savoir qui effectue quel test, mais on ne garantit toujours pas qu'un utilisateur n'effectue qu'un seul test à la fois.
    On ne peut pas ajouter une contrainte d'unicité, puisqu'il est possible que deux tests ne soient pas en cours, donc qu'ils n'aient pas d'utilisateur affecté (dans ce cas deux lignes auraient le marqueur NULL )

    Nous créons donc le trigger suivant :

    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
    19
    20
    21
    22
    23
    24
    25
    CREATE TRIGGER TR_AU_TEST
    	ON TEST
    AFTER UPDATE
    AS
    BEGIN
    	IF UPDATE(IDTesteur)
    	BEGIN
    		DECLARE @listeTesteurs VARCHAR(50)
     
    		-- Recherche si le testeur courant a déjà un test en cours
    		-- et concaténation de leurs identifiants
    		SELECT @listeTesteurs = ISNULL(@listeTesteurs, '') + CAST(I.IDTesteur AS VARCHAR) + ','
    		FROM dbo.TEST T
    		JOIN INSERTED I ON T.IDTesteur = I.IDTesteur
    		GROUP BY I.IDTesteur
    		HAVING COUNT(*) > 1
     
    		IF @listeTesteurs IS NOT NULL -- si le testeur courant a déjà un test en cours
    		BEGIN
    			RAISERROR('Les utilisateurs %s ont déjà un test en cours !', 16, 1, @listeTesteurs)
    			ROLLBACK
    		END
    	END
    END
    GO
    Ensuite, vous créez la procédure stockée qui se chargera de marquer les tests :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE PROCEDURE usp_Teste
    	@_IDTest INT,
    	@_IDTesteur INT
    AS
    BEGIN
    	UPDATE dbo.TEST
    	SET IDTesteur = @_IDTesteur
    	WHERE IDTest = @_IDTest
    END
    Testons, sachant qu'actuellement la colonne IDTesteur de la table TEST a le marqueur NULL pour toutes ses lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXEC dbo.usp_Teste 1, 1
    IDTest nomTest IDTesteur
    ----------- ---------------- -----------
    1 INTEGRATION 1
    2 UNITAIRE NULL
    3 FONCTIONNEL NULL
    4 RECETTE NULL
    5 NON-REGRESSION NULL
    Prenons le test n°2 et affectons-le au même utilisateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    EXEC dbo.usp_Teste 2, 1
    Nous obtenons le message d'erreur suivant :

    Msg*50000, Niveau*16, État*1, Procédure*TR_AU_TEST, Ligne*20
    Les utilisateurs 1, ont déjà un test en cours !
    Msg*3609, Niveau*16, État*1, Procédure*usp_Teste, Ligne*6
    La transaction s'est terminée dans le déclencheur. Le lot a été abandonné.
    C'est le comportement que nous voulions
    N'hésitez pas à poster s'il y a quelque chose d'obscur.

    @++

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 181
    Par défaut
    Merci pour cette magnifique astuce néanmoins, il va me falloir gérer l'accès à cette table via les sessions. Imaginons si un utilisateur est sur une ligne et qu'il se déconnecte, il me faut libérer la ligne pour éviter un blocage intempestif.

    Encore merci, je vais tester cela aujourd'hui

  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
    22 010
    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 : 22 010
    Billets dans le blog
    6
    Par défaut
    C'est exactement pour cela que par principe on ne gère jamais de verrouillage pessimiste dans un SGBDR C/S, sauf si vous voulez des performances lamentables du fait des blocages qui seront induits !

    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...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. gestion des verrous
    Par lucmohamed dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 10/06/2014, 21h43
  2. Gestion des verrous avec ROWLOCK
    Par yoyodemars dans le forum ADO.NET
    Réponses: 16
    Dernier message: 16/02/2012, 20h23
  3. Gestion des verrous
    Par Deciprog dans le forum Administration et Installation
    Réponses: 2
    Dernier message: 23/03/2010, 21h19
  4. comprondre la gestion automatique des verrous
    Par maamar1979 dans le forum Développement
    Réponses: 1
    Dernier message: 02/03/2009, 11h20
  5. c: gestion des exceptions
    Par vince_lille dans le forum C
    Réponses: 7
    Dernier message: 05/06/2002, 14h11

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