แก้ไข: เนื่องจาก@MaxVernonชี้ให้เห็นต่อไปนี้ไม่แนะนำให้ใช้ NOLOCKและฉันควรกล่าวถึงการตั้งค่าระดับการทำธุรกรรมเป็นอย่างดีREAD UNCOMMITED
และให้ความหมายเชิงลบมีอยู่มากกว่าที่จะNOLOCK
ปรากฏขึ้นในตอนแรก ดังนั้นตามที่โพสต์เดิม:
วิธีที่ง่ายและรวดเร็วคือ "ใช่แบบสอบถามแรกจะบล็อกข้อความค้นหาที่สองยกเว้นว่ามีการระบุคำใบ้ดัชนีเฉพาะ ( NOLOCKบางครั้งเรียกว่า" อ่านสกปรก ") หรือตั้งระดับการแยกธุรกรรมของแบบสอบถามที่สองเป็นREAD UNCOMMITED
(ซึ่งทำงานเหมือนกัน) ไม่มันไม่ได้ "
ในการตอบสนองต่อรายละเอียดเพิ่มเติมที่ให้ไว้ในคำถามที่เกี่ยวข้องกับการรวมของWITH
ประโยคที่สองSELECT
เป็นพิเศษร่วมกันหรืออย่างอื่นปฏิสัมพันธ์ระหว่างทั้งสองแบบสอบถามจะส่วนใหญ่เหมือนกัน
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'Foo'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.Foo;
CREATE TABLE dbo.Foo
(
Foo_PK BIGINT IDENTITY( 1, 1 ) NOT NULL,
PRIMARY KEY ( Foo_PK ),
Bar BIT,
x BIT,
y BIT,
z BIT
);
CREATE NONCLUSTERED INDEX IX_Foo_x
ON dbo.Foo ( x );
INSERT INTO dbo.Foo ( Bar, x, y, z )
VALUES ( 1, 1, 1, 1 ), ( 0, 0, 0, 0 );
END;
GO
BEGIN TRANSACTION;
UPDATE dbo.Foo
SET y = 0
WHERE x = 1;
-- COMMIT TRANSACTION;
ในเซสชั่นแยกต่างหากเรียกใช้ต่อไปนี้:
SELECT *
FROM dbo.Foo WITH ( NOLOCK );
GO
SELECT *
FROM dbo.Foo;
คุณสามารถตรวจสอบล็อคปัจจุบันที่มีอยู่โดยการทำงานsp_lock
โดยเฉพาะอย่างยิ่งในเซสชั่นที่แยกต่างหากอื่น:
EXECUTE dbo.sp_lock;
คุณควรเห็นKEY
ประเภทการล็อกที่ถูกเก็บไว้โดย spid ที่ทำธุรกรรมการแทรกในX
โหมด (พิเศษ) เพื่อไม่ให้สับสนกับการIX
ล็อคอื่น ๆ(Intent-Exclusive) ล็อคเอกสารแสดงให้เห็นว่าในขณะที่KEY
ล็อคเป็นช่วงที่เฉพาะเจาะจงก็ยังช่วยป้องกันการทำธุรกรรมอื่น ๆ จากการแทรกหรือปรับปรุงคอลัมน์ได้รับผลกระทบโดยการเปลี่ยนแปลงข้อมูลที่อยู่ในนั้นเพื่อที่จะสามารถอยู่ในช่วงของการค้นหาเดิมที่ เนื่องจากล็อคตัวเองถูกเก็บไว้เป็นพิเศษแบบสอบถามแรกคือการป้องกันการเข้าถึงทรัพยากรจากการทำธุรกรรมที่เกิดขึ้นพร้อมกันอื่น ๆ ผลแถวทั้งหมดของคอลัมน์จะถูกล็อคไม่ว่าจะอยู่ในช่วงที่ระบุโดยแบบสอบถามแรกหรือไม่ก็ตาม
S
ล็อคถูกจัดขึ้นโดยช่วงที่สองจึงจะWAIT
จนX
ล้างล็อคป้องกันไม่ให้อีกX
(หรือU
) ล็อคจากการถูกนำทรัพยากรนั้นจาก spid พร้อมกันแตกต่างกันก่อนช่วงที่สองเสร็จสิ้นการดำเนินการอ่านของตนสมควรดำรงอยู่ของS
ล็อค
ตอนนี้การแก้ไขเพื่อความชัดเจน: นอกจากว่าฉันเข้าใจผิดในสิ่งที่สกปรกอ่านมาจากคำอธิบายสั้น ๆ ของความเสี่ยงที่กล่าวถึงที่นี่ ... แก้ไข 3 : ฉันเพิ่งรู้ว่าฉันไม่ได้พิจารณาผลกระทบของจุดตรวจพื้นหลังที่เขียนเป็น จากธุรกรรมที่ยังไม่ได้รับการยอมรับไปยังดิสก์ดังนั้นใช่คำอธิบายของฉันทำให้เข้าใจผิด
ในแบบสอบถามที่สองชุดแรกสามารถ (และในกรณีนี้จะ) ส่งคืนข้อมูลที่ไม่มีข้อผูกมัด ชุดที่สองที่ทำงานในระดับการแยกธุรกรรมเริ่มต้นREAD COMMITED
จะกลับมาหลังจากเสร็จสิ้นการยอมรับหรือย้อนกลับในเซสชั่นแรก
จากที่นี่คุณสามารถดูแผนแบบสอบถามของคุณและระดับล็อคที่เกี่ยวข้อง แต่ยังดีกว่าคุณสามารถอ่านทั้งหมดเกี่ยวกับการล็อคใน SQL Server ที่นี่
SELECT * FROM Table1
หากเป็นสิ่งที่ฉันต้องการ?