9
votes

Comment effectuer une serrure de rangée?

Je veux verrouiller un enregistrement et que personne ne peut apporter des modifications à cet enregistrement. Lorsque je relâche la serrure, les gens peuvent changer l'enregistrement.

En attendant qu'un enregistrement est verrouillé, je souhaite montrer à l'utilisateur un avertissement que l'enregistrement est verrouillé et que les modifications ne sont pas autorisées.

Comment puis-je faire cela?

J'ai essayé tous les niveaux d'isolation, mais aucun d'entre eux n'a le comportement que je veux. Certains des niveaux d'isolement attendent que la serrure soit libérée, puis effectuez un changement. Je ne veux pas cela, car la mise à jour n'est pas autorisée pour le moment un enregistrement est verrouillé.

Que puis-je faire pour verrouiller un enregistrement et nier tous les changements?

J'utilise SQL Server 2008


1 commentaires

Cela dépend de la base de données. Lequel?


4 Réponses :


0
votes

Voir ce Dupliquer la question sur donc.

Il est essentiellement: p> xxx pré>

archive forte> p>

quelque chose comme ceci peut-être? p>

if exists (
select top 1 1 
from deleted d 
join inserted i on i.id = d.id
where d.IsLocked = 1 and i.RowVersion <> d.RowVersion)
begin
print 'Row is locked'
rollback tran
end


1 commentaires

J'ai essayé cela, mais je suis toujours capable de sélectionner des données et lorsque j'effectue une mise à jour, l'instruction attend jusqu'à ce que la verrouillage soit libérée, puis effectue la mise à jour. Ce n'est pas ce que je veux. Je veux informer l'utilisateur si un enregistrement est verrouillé.



1
votes

SQL Server a des indices de verrouillage, mais ceux-ci sont limités au champ d'application d'une requête.

Si la décision de verrouiller l'enregistrement est prise dans une application, vous pouvez utiliser les mêmes mécanismes que le verrouillage optimiste et refuser toute modification de l'enregistrement de l'application.

Utilisez un horodatage ou un guid comme une serrure sur l'enregistrement et nier l'accès ou les modifications à l'enregistrement si la touche de verrouillage incorrecte est donnée. Soyez prudent de déverrouiller des enregistrements à nouveau ou vous obtiendrez des orphelins


2 commentaires

J'ai pensé à une telle approche, mais si l'application se bloque? Ou si le serveur tombe en panne. Comment puis-je déverrouiller l'enregistrement dans une telle situation?


Il n'y a pas de moyen facile, je pense. Faire expirer les verrous en enregistrant une date d'heure à laquelle il a été verrouillé et utilise un travail de déclenchement ou d'un travail planifié pour nettoyer les serrures trop longs. Ce que vous faites essentiellement est le verrouillage pessimiste. Voir également ceci: Stackoverflow.com/questions/386162/pessimistique -lock-in-t-sql



10
votes

En supposant que ce serveur MS SQL, vous voulez probablement UPDLOCK code>, éventuellement combiné avec ROWLOCK code> ( conseils de table ). Je vais avoir du mal à trouver un article décent qui décrit la théorie, mais voici par exemple rapide:

SELECT id From mytable WITH (ROWLOCK, UPDLOCK) WHERE id = 1 


3 commentaires

Lorsque j'utilise cela, l'instruction UPDATE attend jusqu'à ce que le verrouillage soit libéré, puis effectuez une mise à jour. Je ne veux pas ce comportement. Dès que l'enregistrement est bloqué, l'utilisateur doit voir un message. Cela fait de cette façon, je ne peux pas informer l'utilisateur car l'instruction de mise à jour attend jusqu'à ce que le verrou soit libéré. Je souhaite que la déclaration de mise à jour s'arrête et donnez une erreur / exception / avertissement afin que je puisse notifier à l'utilisateur.


@Martijn - Votre deuxième instruction de mise à jour doit être exécutée avec le NEMAIT indice, ce qui le fera de retourner dès qu'une serrure est rencontrée plutôt que d'attendre le délai d'attente.


La déclaration ne devrait-elle pas lire SELECT ID de MyTable avec (Rowlock, Updlock) où ID = 1 ?



0
votes

Vous ne voulez pas attendre que le verrou soit libéré et affichez le message dès que vous rencontrez une serrure, si c'est le cas, avez-vous essayé NOWAIT . Voir Conseils de table (transact-sql) et SQL Server 2008 Table Conseils Pour plus de détails. Pour bénéficier de NOWAIT Vous devez verrouiller des enregistrements sur les modifications, Google pour plus de détails.


0 commentaires