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 :

[SQL Server 2000] Verrouiller une table


Sujet :

MS SQL Server

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : Pays-Bas

    Informations forums :
    Inscription : Décembre 2005
    Messages : 186
    Points : 133
    Points
    133
    Par défaut [SQL Server 2000] Verrouiller une table
    Bonjour,

    Je viens de lire les FAQs au sujet du verrouillage, mais je ne trouve pas exactement ce que je cherche.
    Tout d'abord pourquoi je souhaite verrouiller ma table : j'ai une page ASP qui execute 3 requetes dans l'ordre suivant :
    1- Insertion dans une table
    2- Recuperation de la valeur du champ auto-increment
    3- Insertion dans une autre table en utilisant comme reférence la valeur qu'on a récuperé en (2)
    Il faut donc que je sois absoluement sur que la valeur récuperée a l'etape 2 corresponde bien a celle qui a été inserer à l'étape 1. Je veux donc placer un verrou d'ecriture sur ma table avant l'étape 1 et le liberer apres l'étape 2 lorsque j'ai recuperé ma valeur.

    Je ne trouve pas comment faire. Je vois dans les FAQs que je dois utiliser WITH (TABLOCK), mais je ne sais pas ou le placer dans une commande INSERT (apparement je ne le place pas au bon endroit), et surtout je ne connais pas la commande sur SQL Sever pour libérer le verrou (c'est carrement génant ), j'ai essayé le UNLOCK TABLE que j'utilisais sous MySQL mais ca n'est pas reconnu.

    Merci !

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    434
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 434
    Points : 502
    Points
    502
    Par défaut
    Bonjour,

    je ne vais pas répondre directement à ta question mais plutôt de donner un conseil. A vouloir jouer avec les lock et unlock (au passage c'est le mot clé NOLOCK ), tu vas te brûler les ailes et avoir pleins d'erreurs à gérer .

    Par contre, change ta façon de gérer ta problématique de récupérer absolument la valeur auto-indentée sure et certaine de ta valeur insérée.

    Fait tout simplement une procédure stockée qui retourne, après insertion, la valeur auto-incrémentéé ! En faisant cela dans une transaction (donc en "local"), t'a pas à gérer les accès concurrents de la sorte

    très schématisuement, un truc de genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE PROCEDURE SP_TOTO @val varchar(10) @VALAUTOINC int output
    AS
    BEGIN
     
    BEGIN TRANS
    SET @VALAUTOINC = NEWID()
    INSERT INTO TOTO
    SELECT @VALAUTOINC, @VAL
    COMMIT TRANS
    END
    PS : tu peux aussi utiliser RETURN

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 847
    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 847
    Points : 52 961
    Points
    52 961
    Billets dans le blog
    6
    Par défaut
    Contrairement à certains SGBDR qui ne savent pas faire des transactions ou ne vérrouillent pas nativement les données nécessaires à un traitement, SQL server fait cela tel que la norme SQL l'a prévu c'est à dire automatiquement et à bon escient.
    En revanche, l''utilisation directe de verrous est possible mais à très haut risque !

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- 1- Insertion dans une table 
    INSERT INTO MaTable VALUES (...)
     
    -- 2- Recuperation de la valeur du champ auto-increment
    -- inutile !!!
     
    -- 3- Insertion dans une autre table en utilisant comme reférence la valeur qu'on a récuperé en (2)
     
    INSERT INTO MonAutreTable VALUES (... @@IDENTITY...)
    C'est tout ce qu'il y a à faire...
    En effet la variable de session @@IDENTITY contient le dernier identifiant attribué quelque soit la table, mais pour la session en cours.
    Il n'y a donc aucune ambiguité et pas de problème de concurrence possible.

    Il faut donc que je sois absoluement sur que la valeur récuperée a l'etape 2 corresponde bien a celle qui a été inserer à l'étape 1. Je veux donc placer un verrou d'ecriture sur ma table avant l'étape 1 et le liberer apres l'étape 2 lorsque j'ai recuperé ma valeur.
    Tout cela est parfaitement inutile avec SQL Server !

    Pour un vernis culturel sur les mécanismes procédural de MS SQL Server, je vous invite à lire l'article que j'ai écrit à ce sujet : http://sqlpro.developpez.com/cours/s...r/transactsql/

    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/ * * * * *

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : Pays-Bas

    Informations forums :
    Inscription : Décembre 2005
    Messages : 186
    Points : 133
    Points
    133
    Par défaut
    Merci pour vos réponses !

    l'utilisation de @@identity me parait en effet assez simple et pratique, cela dit j'aimerais bien en comprendre l'utilisation, qu'entendez vous par "mais pour la session en cours.", dans mon cas, c'est a dire l'exécution de commande dans un script ASP via de l'ADODB, a quelle moment ma session est elle intialisée et quand est t'elle détruite ? Est ce que ma session est initialisée au moment de la creation d'un objet Command ? Si oui, est ce quand je détruis l'objet que je ferme la session ? Parce que si c'est bien le cas il faut que je maintienne ma session au cours de l'execution de ces 2 requêtes.

    Merci pour le lien sur les mécanismes procédurales SQL Server, je vais me pencher dessus parce que pour le moment je n'y connais absolument rien.

    @ZERS : C'est vrai que c'est toujours la galère de verouiller des tables, mais je ne connaissais pas l'existence de @@indentity, et je n'aurais pas penser a écrire de procédures stockées, je viens de MySQL et tout ca ca n'existe pas sur MySQL, donc j'avais gardé le vieux reflexe du LOCK/UNLOCK table ; dans mon cas cependant je pense que le danger du Lock/unlock etait faible car ma table n'est appelée que dans 2 pages dont une seule dans laquelle il y a une écriture dans la table. Enfin cela dit je suis content de pouvoir éviter le verrou sur la table

  5. #5
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    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 573
    Points : 4 043
    Points
    4 043
    Par défaut
    Bonjour,

    La session, c'est la connexion (terminologie OLE DB). @@IDENTITY est valable dans la connexion. Si tu envoies deux commandes dans la même connexion, c'est bon.

    Mon conseil : crée une procédure stockée qui fait tout en un seul appel de ton client, et utilise SCOPE_IDENTITY() à la place de @@IDENTITY, qui te garantit de retourner la valeur identity insérée dans ce scope (cad ta procédure stockée).
    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

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : Pays-Bas

    Informations forums :
    Inscription : Décembre 2005
    Messages : 186
    Points : 133
    Points
    133
    Par défaut
    Merci pour ta réponse !
    Ca me semble donc clair, par contre je vais devoir poster une question sur le forum ASP (a moins que l'un de vous ait la réponse, ce qui m'eviterait d'inonder le forum en créant des sujets) parce que je ne sais pas quand est ouverte ma connexion ni quand elle se termine , d'habitude en ASP lorsqu'on crée un objet command, on lui passe un objet Connection comme étant la connexion active de la facon suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Set obj_Command.ActiveConnection = obj_Connection
    Mais moi je ne crée nulle part d'objet connexion, j'instancie ActiveConnection en lui passant une chaine avec dsn login et password ; du coup je ne sais pas quand ma connexion se termine exactement, est ce que chaque appel d'un objet command créer dans ce cas une nouvelle connexion qui se termine des que je détruit mon objet command ?

    Sinon, je ne suis pas sur de pouvoir passer par une procédure, parce qu'en réalité, le nombre de requete a mon étape 3 n'est pas fixe, parfois je n'en ai qu'une parfois j'en ai plus et parfois aucune, donc je ne sais pas exactement comment je pourrais résoudre ca avec une procédure stockée, dans ce cas je ne sais pas combien de paramètre il faudrait que je passe a ma procédure stockée, a moins que je puisse passer un tableau comme parametre ? dans tous les cas si c'est faisable il faut vraiment que je me penche d'abord sur la doc pour pouvoir en écrire.

  7. #7
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Dans ton code, il y'a forcement un endroit ou vous avez ouvert votre connection avec la méthode open de l'object ADODB.Connection crée.

    C'est à cet endoit que ta cession s'ouvre.

    Découvrez la FAQ de MS SQL Server.
    La chance accorde ses faveurs aux esprits avertis !

Discussions similaires

  1. [SQL-SERVER 2000] Mettre une table en mémoire
    Par usf70 dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 07/12/2007, 23h31
  2. [SQL SERVER 2005] Exporter une table en Access
    Par Golzinne dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 16/03/2007, 17h08
  3. [SQL SERVER 2005] Ouvrir une table en exclusif
    Par olbi dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 02/03/2007, 18h58
  4. [SQL Server] Filtré sur une table avant une jointure externe
    Par TangoZoulou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 06/11/2006, 15h52
  5. [SQL Server 2000] ajouter une colonne identité dans une vue?
    Par CetTer dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 02/08/2005, 13h43

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