UPDLOCK hakkında kafam karıştı, HOLDLOCK


92

Tablo İpuçlarının kullanımını araştırırken şu iki soruyla karşılaştım:

Her iki sorunun cevabı (UPDLOCK, HOLDLOCK), diğer işlemlerin bu tablodaki verileri okuyamayacağını söylüyor, ancak ben bunu görmedim. Test etmek için bir tablo oluşturdum ve iki SSMS penceresi başlattım. İlk pencereden çeşitli tablo ipuçlarını kullanarak tablodan seçilen bir işlemi çalıştırdım. İşlem devam ederken, ikinci pencereden hangisinin engelleneceğini görmek için çeşitli ifadeler çalıştırdım.

Test tablosu:

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]

SSMS Penceresi 1'den:

BEGIN TRANSACTION

SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'

COMMIT TRANSACTION

SSMS Penceresinden 2 (aşağıdakilerden birini çalıştırdı):

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'

Farklı tablo ipuçlarının Pencere 2'de çalıştırılan ifadeler üzerindeki etkisi:

           (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

Bu sorularda verilen cevapları yanlış mı anladım yoksa testlerimde bir hata mı yaptım? Değilse, neden kullanmak istiyorsunuz (UPDLOCK, HOLDLOCK)vs (HOLDLOCK)yalnız?


Neyi başarmaya çalıştığımla ilgili daha fazla açıklama:

Bir tablodan satır seçmek ve bu tablodaki verilerin ben onu işlerken değiştirilmesini önlemek istiyorum. Bu verileri değiştirmiyorum ve okumaların gerçekleşmesine izin vermek istiyorum.

Bu cevap açıkça (UPDLOCK, HOLDLOCK)okumaları engelleyeceğini söylüyor (istediğimi değil). Bu yanıta ilişkin yorumlar, HOLDLOCKokumayı engelleyen şeyin bu olduğunu ima etmektedir . Tablo ipuçlarının etkilerini denemek ve daha iyi anlamak ve UPDLOCKtek başına istediğimi yapıp yapamayacağını görmek için yukarıdaki deneyi yaptım ve bu cevaplarla çelişen sonuçlar aldım.

Şu anda, (HOLDLOCK)kullanmam gereken şeyin bu olduğuna inanıyorum , ancak bir hata yapmış olabileceğimden veya gelecekte beni ısırmak için geri gelecek bir şeyi, dolayısıyla bu soruyu gözden kaçırmış olabileceğimden endişe ediyorum.

Yanıtlar:


104

UPDLOCK bloğu neden seçer? Kilit uyumluluğu Matrix açıkça gösterir Ngibi S / U ve U / S çekişme için hiçbir Çatışma .

HOLDLOCK ipucuna gelince , dokümantasyon şu şekildedir:

HOLDLOCK: SERIALIZABLE ile eşdeğerdir. Daha fazla bilgi için, bu konunun devamında SERİLEŞTİRİLEBİLİR konusuna bakın.

...

SERİLEŞTİRİLEBİLİR: ... Tarama, SERİLEŞTİRİLEBİLİR izolasyon seviyesinde çalışan bir işlemle aynı anlam bilgisiyle gerçekleştirilir ...

ve İşlem Yalıtım Düzeyi konusu SERİLEŞTİRİLEBİLİR'in ne anlama geldiğini açıklar:

Mevcut işlem tamamlanana kadar geçerli işlem tarafından okunan verileri başka hiçbir işlem değiştiremez.

Diğer işlemler, geçerli işlem tamamlanana kadar geçerli işlemdeki herhangi bir ifade tarafından okunan anahtar aralığına denk gelen anahtar değerlerine sahip yeni satırlar ekleyemez.

Bu nedenle, gördüğünüz davranış, ürün belgelerinde mükemmel bir şekilde açıklanmıştır:

  • UPDLOCK eşzamanlı SEÇİMİ veya INSERT'i engellemez, ancak T1 tarafından seçilen satırların herhangi bir GÜNCELLENMESİNİ veya SİLİNMESİNİ engeller.
  • HOLDLOCK SERALIZABLE anlamına gelir ve bu nedenle de seçer sağlar, ancak blok UPDATE ve T1 tarafından seçilen satır silme, yanı sıra, T1 seçilen aralığında herhangi bir INSERT (tüm tablo, bu nedenle herhangi bir ek).
  • (UPDLOCK, HOLDLOCK): deneyiniz, yukarıdaki duruma ek olarak neyi engelleyeceğini, yani T2'de UPDLOCK ile yapılan başka bir işlemi göstermiyor :
    SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
  • TABLOCKX açıklamaya gerek yok

Asıl soru, ne başarmaya çalışıyorsun ? Kilit ipuçlarıyla oynamak, kilitleme semantiğinin% 110'luk mutlak tam anlayışı sorun için yalvarıyor ...

OP düzenlemesinden sonra:

Bir tablodan satır seçmek ve bu tablodaki verilerin ben onu işlerken değiştirilmesini önlemek istiyorum.

Daha yüksek işlem izolasyon seviyelerinden birini kullanmalısınız. TEKRARLANABİLİR OKUMA, okuduğunuz verilerin değiştirilmesini önleyecektir. SERIALIZABLE, okuduğunuz verilerin değiştirilmesini ve yeni verilerin eklenmesini önleyecektir . İşlem izolasyon düzeylerini kullanmak, sorgu ipuçlarını kullanmak yerine doğru yaklaşımdır. Kendra Little'ın izolasyon seviyelerini anlatan güzel bir posteri var .


+1 ve ayrıntılı yanıt için teşekkür ederim. Amacımın ayrıntılarını eklemek için sorumu güncelleyeceğim.
Jeff Ogata

1
@Remus Rusanu, sorgu ipuçlarını kullanmak yerine neden doğru yaklaşımın izolasyon seviyelerini kullandığını açıklar mısınız? Sadece iki tablonun değiştirilmesini kilitlemem gereken bir prosedürüm var ve TABLOCK, HOLDLOCK kullanıyorum, gerçekten izolasyon seviyesine geçmeli ve işlemimdeki tüm tabloları kilitlemeli miyim?
Steve

TABLOCKX için açıklama yapmak istiyorum :)
niico

Not: Kendra Little için blog girişi bağlantısı bir 404 döndürüyor. Bağlantının önerdiği gibi, 2 Şubat 2011 tarihli bir giriş bulamıyorum.
Bacon Bits

22

UPDLOCK, gelecekteki bir güncelleme ifadesi için bir select ifadesi sırasında bir satırı veya satırları kilitlemek istediğinizde kullanılır. Gelecekteki güncelleme, işlemdeki bir sonraki ifade olabilir.

Diğer oturumlar hala verileri görebilir. UPDLOCK ve / veya HOLDLOCK ile uyumsuz kilitleri elde edemezler.

Diğer oturumların kilitlediğiniz satırları değiştirmesini engellemek istediğinizde UPDLOCK'u kullanırsınız. Kilitli satırları güncelleme veya silme yeteneklerini kısıtlar.

Diğer oturumların baktığınız herhangi bir veriyi değiştirmesini önlemek istediğinizde HOLDLOCK'u kullanırsınız. Kilitlediğiniz satırları ekleme, güncelleme veya silme yeteneklerini kısıtlar. Bu, sorguyu yeniden çalıştırmanıza ve aynı sonuçları görmenize olanak tanır.


1
Teşekkür ederim, ama sorumu gerçekten cevapladığınızı sanmıyorum: bu soruların cevapları (UPDLOCK,HOLDLOCK)blok okumaları belirtirken yanlış mıydı (UPDLOCK,HOLDLOCK)ve sadece yerine kullanmak için bir neden var (HOLDLOCK)mı?
Jeff Ogata

İkinci ifadem sorunuzu yanıtlıyor, yanılıyorlar. Diğer oturumlar hala verileri okuyabilir.
Scott Bruns

Updlock, Holdlock, holdlock ile aynı değildir. Updlock, holdlock güncelleme için satırları kilitler ve işleminizi seri hale getirir. Holdlock kendi başına işleminizi seri hale getirir. Daha fazla erişim için seçilen satırları kilitlemez.
Scott Bruns

"UPDLOCK, gelecekteki bir güncelleme ifadesi için bir select ifadesi sırasında bir satırı veya satırları kilitlemek istediğinizde kullanılır." XLOCK bazen çalışmayabileceğinden bunu seviyorum
Yiping
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.