ทำไม UPDLOCK ทำให้ SELECT เลือกที่จะหยุด (ล็อค)?


13

ฉันมีตัวเลือกใน SQL Server ที่ล็อคทั้งตาราง

นี่คือสคริปต์การตั้งค่า (ตรวจสอบให้แน่ใจว่าคุณไม่ได้เขียนทับอะไรเลย)

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

เปิดหน้าต่างแบบสอบถามใหม่และเรียกใช้ธุรกรรมต่อไปนี้ (ซึ่งมีการรออยู่):

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

และอีกอันที่จะทำงาน (ให้แน่ใจว่าพวกเขาทำงานในเวลาเดียวกัน):

USE [LockingTestDB]
GO

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

USE [master]
GO

คุณจะสังเกตเห็นว่าคำค้นหาที่สองจะถูกบล็อกโดยคำถามแรก หยุดการสืบค้นแรกและรัน ROLLBACK และครั้งที่สองจะเสร็จสมบูรณ์

ทำไมสิ่งนี้จึงเกิดขึ้น

PS: การเพิ่มดัชนีที่ไม่ได้ทำคลัสเตอร์ (ที่มีความครอบคลุมเต็ม) มากกว่าชื่อจะแก้ไขได้:

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

ทำไมอีกครั้ง

คำตอบ:


19

ดังที่บันทึกไว้ใน Books Onlineให้UPDLOCKล็อคการอัปเดตและเก็บไว้ที่ส่วนท้ายของธุรกรรม

หากไม่มีดัชนีเพื่อค้นหาแถวที่จะล็อคแถวที่ผ่านการทดสอบทั้งหมดจะถูกล็อคและล็อคในแถวที่มีคุณสมบัติเหมาะสมจะถูกเก็บไว้จนกว่าธุรกรรมจะเสร็จสมบูรณ์

ธุรกรรมแรกถือล็อคการปรับปรุงในแถวที่ชื่อ = 1 ธุรกรรมที่สองถูกบล็อกเมื่อพยายามรับล็อคการปรับปรุงในแถวเดียวกัน (เพื่อทดสอบว่าชื่อ = 2 สำหรับแถวนั้น)

ด้วยดัชนี SQL Server สามารถค้นหาและล็อคเฉพาะแถวที่มีคุณสมบัติได้อย่างรวดเร็วดังนั้นจึงไม่มีข้อขัดแย้ง

คุณควรตรวจสอบรหัสกับผู้เชี่ยวชาญด้านฐานข้อมูลที่มีคุณสมบัติเหมาะสมเพื่อตรวจสอบเหตุผลของคำใบ้ล็อคและเพื่อให้แน่ใจว่ามีดัชนีที่เหมาะสม

ข้อมูลที่เกี่ยวข้อง: การแก้ไขข้อมูลภายใต้การอ่าน Snapshot Isolation

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.