UPDLOCK neden SELECT'lerin kilitlenmesine (kilitlenmesine) neden oluyor?


13

Tüm tabloyu kilitleyen SQL SERVER bir seçim var.

İşte kurulum komut dosyası (hiçbir şeyin üzerine yazmadığınızdan emin olun)

USE [master]
GO

IF EXISTS(SELECT 1 FROM sys.databases d WHERE d.name = 'LockingTestDB')
DROP DATABASE LockingTestDB
GO

CREATE DATABASE LockingTestDB
GO

USE [LockingTestDB]
GO
IF EXISTS(SELECT 1 FROM sys.tables t WHERE t.name = 'LockingTestTable')
  DROP TABLE LockingTestTable
GO

CREATE TABLE LockingTestTable (
  Id int IDENTITY(1, 1),
  Name varchar(100),
  PRIMARY KEY CLUSTERED (Id)
)
GO

INSERT INTO LockingTestTable(Name) VALUES ('1')
INSERT INTO LockingTestTable(Name) VALUES ('2')
GO

Yeni bir sorgu penceresi açın ve (içinde bir bekleme süresi olan) aşağıdaki işlemi çalıştırın:

USE [LockingTestDB]
GO

BEGIN TRANSACTION
  SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '1'
  WAITFOR DELAY '00:01:00'

COMMIT TRANSACTION
--ROLLBACK
GO

USE [master]
GO

Ve çalışacak başka bir tane (aynı anda çalıştıklarından emin olun):

USE [LockingTestDB]
GO

SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '2'

USE [master]
GO

İkinci sorgunun birincisi tarafından engelleneceğini fark edeceksiniz. İlk sorguyu durdurun ve ROLLBACK'i çalıştırın, ikinci sorguyu tamamlayın.

Bu neden oluyor?

Not: Ad üzerine kümelenmemiş bir dizin (tam kapsamlı) eklemek sorunu düzeltir:

USE [LockingTestDB]
GO

CREATE NONCLUSTERED INDEX [IX_Name] ON [dbo].[LockingTestTable] 
(
  [Name] ASC
)
INCLUDE ( [Id]) WITH (STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

Yine neden?

Yanıtlar:


19

Books Online'da belgelendiği gibi , UPDLOCKgüncelleme kilitlerini alır ve bunları işlemin sonuna kadar tutar.

Kilitlenecek satırları bulmak için bir dizin olmadan, test edilen tüm satırlar kilitlenir ve işlem tamamlanana kadar uygun satırlardaki kilitler tutulur.

İlk işlemde name = 1 olan satırda bir güncelleme kilidi bulunur. İkinci işlem, aynı satırda bir güncelleme kilidi almaya çalıştığında engellenir (bu satır için name = 2 olup olmadığını test etmek için).

Bir dizinde SQL Server hızlı bir şekilde yalnızca uygun olan satırları bulabilir ve kilitleyebilir;

Kilitleme ipucunun nedenini doğrulamak ve uygun dizinlerin mevcut olduğundan emin olmak için kodu kalifiye bir veritabanı uzmanı ile incelemelisiniz.

İlgili bilgiler: Taahhüt Edilen Anlık Görüntü Yalıtımı altındaki Veri Değişiklikleri

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.