Lors de la recherche sur l'utilisation des conseils de table mes , je suis tombé sur ces deux questions:
Les réponses aux deux questions indiquent que lors de l'utilisation (UPDLOCK, HOLDLOCK)
, d'autres processus ne pourront pas lire les données de cette table, mais je n'ai pas vu cela. Pour tester, j'ai créé une table et démarré deux fenêtres SSMS. À partir de la première fenêtre, j'ai exécuté une transaction qui a sélectionné dans la table en utilisant divers indices de table. Pendant que la transaction était en cours d'exécution, à partir de la deuxième fenêtre, j'ai exécuté diverses instructions pour voir lesquelles seraient bloquées.
La table de test:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Depuis la fenêtre SSMS 1:
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
À partir de la fenêtre SSMS 2 (a exécuté l'une des opérations suivantes):
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
Effet des différentes indications de table sur les instructions exécutées dans la fenêtre 2:
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
Ai-je mal compris les réponses données à ces questions ou ai-je commis une erreur lors de mes tests? Sinon, pourquoi utiliseriez-vous (UPDLOCK, HOLDLOCK)
vs (HOLDLOCK)
seul?
Explication supplémentaire de ce que j'essaie d'accomplir:
Je voudrais sélectionner des lignes dans une table et empêcher les données de cette table d'être modifiées pendant que je la traite. Je ne modifie pas ces données et je souhaite autoriser les lectures.
Cette réponse dit clairement que (UPDLOCK, HOLDLOCK)
cela bloquera les lectures (pas ce que je veux). Les commentaires sur cette réponse impliquent que c'est cela HOLDLOCK
qui empêche les lectures. Pour essayer de mieux comprendre les effets des indices de table et voir si UPDLOCK
seul ferait ce que je voulais, j'ai fait l'expérience ci-dessus et j'ai obtenu des résultats qui contredisent ces réponses.
Actuellement, je pense que (HOLDLOCK)
c'est ce que je devrais utiliser, mais je crains d'avoir commis une erreur ou oublié quelque chose qui reviendra me mordre à l'avenir, d'où cette question.
la source
UPDLOCK est utilisé lorsque vous souhaitez verrouiller une ou plusieurs lignes pendant une instruction SELECT pour une instruction de mise à jour future. La future mise à jour pourrait être la toute prochaine déclaration de la transaction.
Les autres sessions peuvent toujours voir les données. Ils ne peuvent tout simplement pas obtenir des verrous incompatibles avec UPDLOCK et / ou HOLDLOCK.
Vous utilisez UPDLOCK lorsque vous souhaitez empêcher les autres sessions de modifier les lignes que vous avez verrouillées. Cela limite leur capacité à mettre à jour ou à supprimer des lignes verrouillées.
Vous utilisez HOLDLOCK lorsque vous souhaitez empêcher les autres sessions de modifier les données que vous consultez. Cela limite leur capacité à insérer, mettre à jour ou supprimer les lignes que vous avez verrouillées. Cela vous permet d'exécuter à nouveau la requête et de voir les mêmes résultats.
la source
(UPDLOCK,HOLDLOCK)
bloc de lecture, et y a-t-il une raison d'utiliser(UPDLOCK,HOLDLOCK)
au lieu de simplement(HOLDLOCK)
?