bonjour,
je suis de faire une ptit application avec sql server,
et je veux savoir, est ce qu'il y' a la possibilité de verrouiller seulement une ligne dans une table avec sql server,
j'amurai savoir la syntaxe correspond.
merci à tous
bonjour,
je suis de faire une ptit application avec sql server,
et je veux savoir, est ce qu'il y' a la possibilité de verrouiller seulement une ligne dans une table avec sql server,
j'amurai savoir la syntaxe correspond.
merci à tous
Les lignes sont verrouillées automatiquement par le serveur lors des lectures (verrous partagés) comme lors de écritures (verrous exclusif).
Il n'y a donc rien à faire de particulier.... Un SGBDR n'est pas une tableur !
A +
Merci pour votre réponse; mais je que lorsque un utilisateur entraine de modifier une ligne, aucun autre utilisateur peut consulter cette ligne.
merci
Que faites-vous alors dans le cas où un utilise ouvre une ligne en modification et s'arrête là. Disons qu'il part prendre un café et bloque alors la ligne pendant de très (trop) longue minute.
Pire ! Il ouvre une ligne en modification et renverse ensuite de l'eau sur sa machine la mettant totalement et irrémédiablement hors service. Votre ligne restera alors bloquée.
Bref, pour paraphraser sqlpro d'une manière un peu plus explicite, ce n'est pas une bonne manière de procéder.
(Mais j'imagine que nous avons tous (moi en tout cas) eu ce genre d'idée à nos débuts)
benabdessamed,
Je te proposerais utiliser les timestamps ou numéros des versions pour chaque ligne afin d'assurer le travail dans l'environnement concurrentielle sans avoir les verrouillages.
I.e.
Certains ORM (object relation mapping) comme NHibernate supportent les versions ds objets (lignes des tables) automatiquement après en avoir défini dans un fichier du mapping.
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 CREATE TABLE t1 ( id int primary key, value nvarchar(50), version int ) GO INSERT INTO t1 (1, 'Initial value', 1) GO -- Utilisateur 1 récupère l'info SELECT * FROM t1 -- Utilisateur 2 récupère l'info SELECT * FROM t1 -- Utilisateur 2 MAJ l'info UPDATE t1 SET value = 'New value 2', version = version + 1 WHERE id = 1 AND version = 1 IF @@rowcount = 0 -- @@rowcount = 1 => OK -- Utilisateur 1 MAJ l'info UPDATE t1 SET value = 'New value 1', version = version + 1 WHERE id = 1 AND version = 1 IF @@rowcount = 0 -- @@rowcount = 0 => erreur à traiter : cette ligne à été modifié par quelqu'un
Mais ceci alourdie et ne garantie pas la mise à jour....
A +
Frédéric,
guerre sacrée "verrouillage optimiste vs pessimiste" ?
La bonne pratique est d'éviter les verrouillages ce que la méthode de versionning permet faire. Sinon c'est une question d'isolement des transactions. Mais vu la question initiale je ne pense pas que c'est le bon moment d'en parler.
merci à tous,
concernant "isolement des transactions", vous parlez de " begin transaction ... commit ".
Oui. Pour assurer que la ligne ne sera pas modifiée il s'agit de
Cette approche est loin d'être parfaite et donc les verrouillages logiques devront être implémentés au niveau fonctionnel plutôt qu'au niveau technique (i.e table des documents en rédaction courante par les utilisateurs).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 SET TRANSACTION ISOLATION LEVEL REPEATABLE READ BEGIN TRANSACTION SELECT * FROM maTable WHERE id = 1 -- ici la connexion doit rester ouvert lors de manipulation dans l'application UPDATE maTable SET ... WHERE id = 1 COMMIT
Voir aussi SQL et niveau d'isolement des transactions
non, de la porosité des données lors des transactions.
À me lire : http://sqlpro.developpez.com/isolation-transaction/
A +
durant l'exécution de cette opération, la totalité de la table est inaccessible, n'est pas seulement la ligne sélectionné.
Sans savoir la raison de nécessité de verrouillage je ne pense pas proposer la solution. Et en tous cas la solution doit être applicative.
Bonjour,
J'ai toujours utilisé les locks manuels avec un hint.
Par exemple, lorsque mon utilisateur entre en "modification" sur la fiche d'un client, je veux que ce client ne puisse :
- pas être modifié
- pas être sélectionné
(toute tentative allant dans l'un ou l'autre des des sens devra être mise en attente tant que mon utilisateur n'aura pas terminé la modification)
Donc dans le code client :
1/ Au chargement de la fiche client (en mode modification)
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 begin transaction; select id, nom, age from client with rowlock holdlock;
A partir de là, la ligne en question est lockée. Personne ne peut plus rien faire dessus, ni sélection, ni modification.
2/ La mise à jour : à l'intérieur de la transaction
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 update client set name = 'toto', age = '31' where id = 1;
Ici, c'est toujours locké.
3/ Libération du verrou lorsqu'on quitte la fiche du client :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 rollback; -- ou commit;
Là, tout le monde peut de nouveau accéder à la ligne.
Attention cependant : ce genre de verrous ralenti considérablement la base de données, et peut aboutir sur un dead lock !
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager