“ with (nolock)” ใน SQL Server คืออะไร


610

ใครสามารถอธิบายความหมายของการใช้with (nolock)กับข้อความค้นหาเมื่อคุณควร / ไม่ควรใช้มัน

ตัวอย่างเช่นหากคุณมีแอปพลิเคชันธนาคารที่มีอัตราการทำธุรกรรมสูงและมีข้อมูลจำนวนมากในตารางบางประเภทข้อความค้นหาใดที่ nolock จะใช้ได้ มีกรณีใดบ้างที่คุณควรใช้ / ไม่เคยใช้หรือไม่


ฉันทำการสอบถามย่อยในstackoverflow.com/questions/3836282/ …และstackoverflow.com/questions/3836032/ …ส่วนใหญ่คำตอบของ Jonathan Allen stackoverflow.com/questions/686724/ …
Gennady Vanin ГеннадийВанин

1
ลิงก์เดียวที่นี่ - mssqltips.com/sqlservertip/2470/…
Steam

1
นี่คือบทสรุปที่ยอดเยี่ยมของความหมายของการใช้ NOLOCK blogs.msdn.com/b/davidlean/archive/2009/04/06/…
Bryan

คำตอบ:


461

WITH (NOLOCK) เทียบเท่ากับการใช้ READ UNCOMMITED เป็นระดับการแยกธุรกรรม ดังนั้นคุณจึงมีความเสี่ยงในการอ่านแถวที่ไม่มีข้อผูกมัดซึ่งจะถูกย้อนกลับในภายหลังเช่นข้อมูลที่ไม่เคยทำให้เป็นฐานข้อมูล ดังนั้นในขณะที่มันสามารถป้องกันการอ่านถูกหยุดชะงักโดยการดำเนินงานอื่น ๆ มันมาพร้อมกับความเสี่ยง ในแอปพลิเคชันธนาคารที่มีอัตราการทำธุรกรรมสูงอาจไม่ใช่วิธีที่เหมาะสมในการแก้ไขปัญหาใด ๆ ที่คุณกำลังพยายามแก้ไขด้วย IMHO


156
แอปพลิเคชันธนาคารส่วนใหญ่สามารถใช้ nolock ได้อย่างปลอดภัยเพราะเป็นธุรกรรมในแง่ธุรกิจ คุณเขียนแถวใหม่เท่านั้นคุณไม่เคยอัพเดท
Jonathan Allen

49
@ Grauenwolf- แถวที่แทรก แต่ไม่มีข้อผูกมัดยังสามารถนำไปสู่การอ่านที่สกปรกได้
saasman

16
@ Saasman- หากคุณไม่เคยทำธุรกรรมย้อนกลับนั่นไม่สำคัญ และด้วยตารางแบบแทรกเท่านั้นโอกาสในการย้อนกลับจึงผอมไปไม่มีเลย และหากเกิดขึ้นคุณจะยังคงแก้ไขได้ทั้งหมดในรายงานผลต่างสิ้นวัน
Jonathan Allen

1
ฉันยึดที่มั่น ฉันถือว่าการเพิ่มไม่มีคำใบ้ล็อคอยู่ สำหรับตัวอย่าง:
Ross Bush

11
หากคุณใช้NOLOCKกับSELECTคุณจะเสี่ยงต่อการส่งคืนแถวเดียวกันมากกว่าหนึ่งครั้ง (ข้อมูลซ้ำ) หากมีการแทรกข้อมูล (หรืออัปเดต) ลงในตารางในขณะที่ทำการเลือก
Ian Boyd

170

คำถามคือสิ่งที่เลวร้ายยิ่ง:

  • การหยุดชะงักหรือ
  • ค่าผิดหรือเปล่า?

สำหรับฐานข้อมูลทางการเงินการหยุดชะงักนั้นแย่กว่าค่าที่ผิด ฉันรู้ว่าเสียงข้างหลัง แต่ได้ยินฉัน ตัวอย่างดั้งเดิมของธุรกรรม DB คือคุณอัปเดตสองแถวลบจากหนึ่งและเพิ่มไปยังอีก ว่าเป็นสิ่งที่ผิด.

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

การรับยอดเงินในบัญชีผิดพลาดชั่วคราวไม่ใช่เรื่องใหญ่นั่นคือสิ่งที่การสมานฉันท์สิ้นสุดวัน และเงินเบิกเกินบัญชีจากบัญชีมีแนวโน้มที่จะเกิดขึ้นได้มากเนื่องจากมีการใช้ ATM สองเครื่องในครั้งเดียวมากกว่าเพราะมีการอ่านที่ไม่มีข้อผูกมัดจากฐานข้อมูล

ที่กล่าวว่า SQL Server 2005 แก้ไขข้อบกพร่องส่วนใหญ่ที่ทำให้NOLOCKจำเป็น ดังนั้นถ้าคุณใช้ SQL Server 2000 หรือเก่ากว่าคุณไม่จำเป็นต้องใช้มัน

อ่านเพิ่มเติมการ
กำหนดเวอร์ชันแถวระดับ


22
ได้รับยอดเงินในบัญชีผิดปกติชั่วคราวไม่ใช่เรื่องใหญ่อะไร จะเป็นอย่างไรถ้าการทำธุรกรรมนั้นเป็นสิ่งที่คุณกำลังถอนเงินสดจากตู้เอทีเอ็มโดยไม่ จำกัด วงเงินเบิกเกินบัญชี?
เรียนรู้

13
@Learning: จะเกิดอะไรขึ้นถ้าคุณนำเงินออก 30 วินาทีก่อนที่ใครบางคนจะเรียกเก็บเงินจากบัตรของคุณ? จนกว่าการสื่อสารทั้งหมดจะเกิดขึ้นอย่างบ้าคลั่งเงินเบิกเกินบัญชีจะเป็นความจริงของชีวิต
Jonathan Allen

6
+1 ในแอปทางการเงิน (ทุกที่ไม่เพียง แต่ในธนาคาร) ไม่มีการอัพเดทหรือลบ แม้การดำเนินการที่ไม่ถูกต้องจะถูกแก้ไขโดยการแทรกบันทึก ศัพท์ภาษาอังกฤษนี้คืออะไร? มันเป็น "storno" หรือไม่? Google ไม่ได้ช่วยฉันตอบคำถามนี้
Gennady Vanin ГеннадийВанин

7
การเข้ามาสาย ... การหยุดชะงักควรถูกจับและลองใหม่ สกปรกอ่านมีผลกระทบ
GBN

4
@Janathan อีกครั้งเพียงแค่ fyi, คำว่ามากที่สุด, ไม่ขึ้น
จิมมี่ D

57

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

ตรวจสอบบทความ Itzik เบนกานของ นี่คือข้อความที่ตัดตอนมา:

"ด้วยคำใบ้ NOLOCK (หรือการตั้งค่าระดับการแยกของเซสชันเป็น READ UNCOMMITTED) คุณบอก SQL Server ว่าคุณไม่ได้คาดหวังความมั่นคงดังนั้นจึงไม่มีการรับประกันใด ๆ จำไว้ว่า" ข้อมูลที่ไม่สอดคล้องกัน "ไม่เพียง แต่หมายความว่า คุณอาจเห็นการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดซึ่งถูกย้อนกลับในภายหลังหรือการเปลี่ยนแปลงข้อมูลในสถานะสื่อกลางของธุรกรรมนอกจากนี้ยังหมายความว่าในแบบสอบถามแบบง่ายที่สแกนข้อมูลตาราง / ดัชนีทั้งหมด SQL Server อาจสูญเสียตำแหน่งสแกนหรือคุณอาจสิ้นสุด รับแถวเดียวกันสองครั้ง "


5
อีกหน่อยเขาอธิบายวิธีการรับแถวเดียวกันสองครั้ง: ฉันจะสร้างตาราง T1 ขึ้นใหม่เพื่อให้ดัชนีกลุ่มบน col1 ถูกกำหนดเป็นดัชนีที่ไม่ซ้ำกับตัวเลือก IGNORE_DUP_KEY ซึ่งหมายความว่าค่าที่ซ้ำกันไม่สามารถมีอยู่ใน col1 และความพยายามที่จะแทรกคีย์ที่ซ้ำกันจะไม่ล้มเหลวในการทำธุรกรรมและสร้างข้อผิดพลาด แต่เพียงแค่สร้างคำเตือน หากคุณไม่ได้ใช้ตัวเลือกแปลก ๆ นี้คุณอาจไม่ต้องกังวลกับการได้แถวสองครั้ง
JanHudecek

คุณยังสามารถรับแถว dupe ได้โดยไม่มีตัวเลือกแบบใช้สาย - หากแบบสอบถามของคุณใช้ประโยชน์จากดัชนีที่ไม่ซ้ำตัวอย่างเช่น สิ่งนี้ไม่ได้มีเฉพาะใน nolock
RMD

54

ตัวอย่างหนังสือเรียนเพื่อการใช้งานที่ถูกต้องของคำแนะนำ nolock คือการสุ่มตัวอย่างรายงานกับฐานข้อมูล OLTP ที่อัปเดตสูง

เพื่อนำตัวอย่างเฉพาะ หากธนาคารถนนใหญ่ในสหรัฐต้องการเรียกใช้รายงานรายชั่วโมงเพื่อค้นหาสัญญาณแรกของระดับเมืองที่ดำเนินการกับธนาคารการสอบถาม nolock สามารถสแกนตารางธุรกรรมที่รวมเงินฝากเงินสดและถอนเงินสดต่อเมือง สำหรับรายงานดังกล่าวเปอร์เซ็นต์ของข้อผิดพลาดเล็ก ๆ ที่เกิดจากธุรกรรมการปรับปรุงย้อนกลับจะไม่ลดค่าของรายงาน


31

ไม่แน่ใจว่าทำไมคุณถึงไม่ห่อธุรกรรมทางการเงินในการทำธุรกรรมฐานข้อมูล (เช่นเมื่อคุณโอนเงินจากบัญชีหนึ่งไปยังอีกบัญชีหนึ่ง - คุณไม่ได้ทำธุรกรรมด้านหนึ่งในแต่ละครั้ง - นี่คือเหตุผลว่าทำไมธุรกรรมที่ชัดเจน) แม้ว่ารหัสของคุณจะถูกนำไปใช้ในการทำธุรกรรมทางธุรกิจ แต่ดูเหมือนว่าฐานข้อมูลการทำธุรกรรมทั้งหมดมีแนวโน้มที่จะทำการย้อนกลับโดยปริยายในกรณีที่เกิดข้อผิดพลาดหรือความล้มเหลว ฉันคิดว่าการสนทนานี้เป็นไปในหัวของคุณ

หากคุณมีปัญหาในการล็อคให้ใช้เวอร์ชันและล้างข้อมูลโค้ดของคุณ

ไม่มีการล็อคไม่เพียง แต่คืนค่าที่ไม่ถูกต้อง แต่จะคืนค่าระเบียนที่เป็นค่าแฝง

มันเป็นความเข้าใจผิดทั่วไปที่ทำให้การสืบค้นทำงานได้เร็วขึ้น หากไม่มีการล็อกการเขียนบนโต๊ะมันจะไม่สร้างความแตกต่างใด ๆ หากมีการล็อกบนตารางอาจทำให้แบบสอบถามเร็วขึ้น แต่มีการล็อกเหตุผลที่ถูกคิดค้นขึ้นตั้งแต่แรก

ในความเป็นธรรมต่อไปนี้เป็นสถานการณ์พิเศษสองข้อที่อาจมีประโยชน์จาก nolock

1) ฐานข้อมูลเซิร์ฟเวอร์ sql ก่อนปี 2005 ที่ต้องการเรียกใช้การค้นหาแบบยาวกับฐานข้อมูล OLTP แบบสดซึ่งอาจเป็นวิธีเดียวเท่านั้น

2) แอปพลิเคชันที่เขียนไม่ดีซึ่งล็อคการบันทึกและส่งคืนการควบคุมไปยัง UI และผู้อ่านจะถูกบล็อกอย่างไม่มีกำหนด Nolock มีประโยชน์ที่นี่หากแอปพลิเคชั่นไม่สามารถแก้ไขได้ (บุคคลที่สามเป็นต้น) และฐานข้อมูลเป็นแบบ pre-2005 หรือไม่สามารถเปิดเวอร์ชันได้


11
ฉันเห็นด้วยกับคุณว่าไม่ควรใช้ NOLOCK เพื่อสร้างรหัสที่เขียนไม่ดี อย่างไรก็ตามฉันคิดว่าการโจมตี Johnathan ของคุณนั้นไม่มีเหตุผลเพราะเขาไม่เคยพูดถึงธุรกรรมฐานข้อมูล เขาชี้ให้เห็นว่าโดยทั่วไปแล้วแอปพลิเคชันทางการเงินจะไม่อนุญาตให้มีการแก้ไขเรคคอร์ด (เห็นได้ชัดว่ามีข้อยกเว้นบางประการ) ในตัวอย่างการโอนเงินของคุณเขากำลังบอกว่ามันคงจะแปลกถ้าคุณต้องเปลี่ยนค่าของยอดเงินในบัญชีแทนการเพิ่มรายการเดบิต / เครดิตไปยังบัญชีแยกประเภท
chrnola

19
เมื่อโอนเงินจากบัญชีหนึ่งไปยังอีกบัญชีหนึ่งในธนาคารอื่นคุณคิดว่าอย่างไร uber- ฐานข้อมูลบางคนใช้ล็อกบนโต๊ะที่ Bank of America และอีกแห่งที่ Wells Fargo? ไม่ธุรกรรมทางการเงินถูกเขียนลงในแต่ละรายการจากนั้นกระบวนการสิ้นวันจะตรวจสอบว่าระเบียนทั้งหมดตรงกัน
Jonathan Allen

24

NOLOCKเทียบเท่ากับREAD UNCOMMITTEDแต่ Microsoft บอกว่าคุณไม่ควรใช้UPDATEหรือDELETEคำสั่ง:

สำหรับคำสั่ง UPDATE หรือ DELETE: ฟีเจอร์นี้จะถูกลบใน Microsoft SQL Server รุ่นต่อไป หลีกเลี่ยงการใช้คุณสมบัตินี้ในงานพัฒนาใหม่และวางแผนแก้ไขแอปพลิเคชั่นที่ใช้คุณสมบัตินี้ในปัจจุบัน

http://msdn.microsoft.com/en-us/library/ms187373.aspx

บทความนี้ใช้กับ SQL Server 2005 ดังนั้นการสนับสนุนที่NOLOCKมีอยู่หากคุณใช้รุ่นนั้น เพื่อให้คุณได้รหัสในอนาคต (สมมติว่าคุณได้ตัดสินใจใช้การอ่านสกปรก) คุณสามารถใช้สิ่งนี้ในขั้นตอนการจัดเก็บของคุณ:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


21

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

มันสามารถเร็วขึ้นในการอ่าน แต่ฉันไม่สามารถพูดได้เท่าไหร่

โดยทั่วไปฉันแนะนำให้ใช้มันเพราะการอ่านข้อมูลที่ไม่มีข้อผูกมัดอาจทำให้สับสนได้ดีที่สุด


1
มันจะดีถ้าคุณพูดถึงความจริงที่ว่า SQL Server 2005 มีการกำหนดเวอร์ชันของแถวดังนั้น nolocks ก็ไม่จำเป็นอีกต่อไป
Jonathan Allen

"with (nolock)" ยังคงมีอยู่แม้ใน SQL Server 2005 - แต่ข้อดีก็คือ slimmer และ slimmer นั่นเป็นความจริง
marc_s

18

อีกกรณีหนึ่งซึ่งปกติแล้วมันก็โอเคอยู่ในฐานข้อมูลการรายงานซึ่งข้อมูลอาจแก่แล้วและการเขียนก็ไม่ได้เกิดขึ้น ในกรณีนี้ผู้ดูแลระบบควรตั้งค่าตัวเลือกที่ระดับฐานข้อมูลหรือระดับตารางโดยการเปลี่ยนระดับการแยกเริ่มต้น

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

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


4
ในฐานะคนที่ทำงานกับแอปพลิเคชันธนาคารฉันต้องบอกว่าไม่มีล็อคไม่ได้เป็นปัญหา เร็กคอร์ดธุรกรรมที่เป็นแถวที่แทรก แต่ไม่เคยอัพเดตหรือลบออกไปนั้นมีความต้านทานต่อปัญหาการอ่านข้อมูลที่ไม่ธรรมดา
Jonathan Allen

15

คำตอบง่ายๆ - เมื่อใดก็ตามที่ SQL ของคุณไม่เปลี่ยนแปลงข้อมูลและคุณมีแบบสอบถามที่อาจรบกวนกิจกรรมอื่น ๆ (ผ่านการล็อก)

ควรพิจารณาถึงข้อความค้นหาใด ๆ ที่ใช้สำหรับรายงานโดยเฉพาะอย่างยิ่งหากข้อความค้นหาใช้เวลามากกว่าพูด 1 วินาที

มีประโยชน์อย่างยิ่งหากคุณมีรายงานประเภท OLAP ที่คุณใช้กับฐานข้อมูล OLTP

แต่คำถามแรกที่ถามคือ "ทำไมฉันถึงเป็นห่วงเรื่องนี้" ln ประสบการณ์ของฉัน, fudging พฤติกรรมการล็อกค่าเริ่มต้นมักเกิดขึ้นเมื่อมีคนอยู่ในโหมด "ลองอะไรก็ได้" และนี่เป็นกรณีหนึ่งที่ไม่เกิดผลที่ไม่คาดคิด บ่อยครั้งที่มันเป็นกรณีของการเพิ่มประสิทธิภาพก่อนเวลาอันควรและอาจถูกทิ้งไว้ในแอพพลิเคชั่น "ในกรณี" ได้ง่าย เป็นสิ่งสำคัญที่จะต้องเข้าใจว่าทำไมคุณถึงทำสิ่งนั้นแก้ปัญหาอะไรและคุณมีปัญหาจริงหรือไม่


11

คำตอบสั้น ๆ :

ใช้WITH (NOLOCK)ในคำสั่ง SELECT บนตารางที่มีดัชนีคลัสเตอร์เท่านั้น

คำตอบยาว:

WITH (NOLOCK) มักถูกใช้เป็นวิธีที่วิเศษในการเพิ่มความเร็วในการอ่านฐานข้อมูล

ชุดผลลัพธ์สามารถมีแถวที่ยังไม่ได้ทำซึ่งมักจะย้อนกลับในภายหลัง

หาก WITH (NOLOCK) ถูกนำไปใช้กับตารางที่มีดัชนีที่ไม่ทำคลัสเตอร์แล้วดัชนีแถวสามารถเปลี่ยนแปลงได้โดยการทำธุรกรรมอื่น ๆ เนื่องจากข้อมูลแถวกำลังถูกสตรีมเข้าสู่ตารางผลลัพธ์ ซึ่งหมายความว่าชุดผลลัพธ์อาจหายไปแถวหรือแสดงแถวเดียวกันหลายครั้ง

READ COMMITTED เพิ่มปัญหาเพิ่มเติมที่ข้อมูลเสียหายภายในคอลัมน์เดียวที่ผู้ใช้หลายคนเปลี่ยนเซลล์เดียวกันพร้อมกัน


2
การอ่านข้อมูลที่ไม่มีข้อผูกมัดเป็นที่ยอมรับได้หากไม่เปลี่ยนแปลงการตัดสินใจขั้นสุดท้าย ตัวอย่างเช่นหากคุณพยายามฉายว่าร้านค้าปลีกของคุณใช้เงินไปเท่าไหร่ในอีก 6 เดือนข้างหน้าเพราะเห็นว่าแทมมี่ซื้อผ้าเช็ดตัว 2 ม้วนเมื่อเธอซื้อ 3 จริง ๆ จะไม่เปลี่ยนความคิดเห็นของคุณในอนาคต .
Jonathan Allen

1
หากตัวกรองของคุณรวมอยู่ในตอนนี้ข้อมูลของคุณจะไม่ถูกต้องทันทีที่คุณเรียกใช้แบบสอบถาม หากตัวกรองของคุณมีเฉพาะข้อมูลประวัติการใช้READ UNCOMITTED จะไม่มีผลกับตัวกรองเลย มีเหตุผลที่รวมอยู่ในมาตรฐาน ANSI
Jonathan Allen

2
ไม่เคยพูดไม่เคย หากคุณต้องการข้อมูลที่ถูกต้อง 100% คุณไม่ควรใช้ nolock สำหรับฉันมันมักจะไม่เป็นเช่นนั้น เมื่อนำเสนอข้อมูลไปยังผู้ใช้ตามเวลาที่พวกเขาดำเนินการกับข้อมูลอาจมีการเปลี่ยนแปลงอยู่แล้ว แต่ส่วนใหญ่ไม่ได้และการโต้แย้งการล็อคไม่คุ้มค่าความล่าช้าในการตอบสนอง
Perposterer

มายึดติดกับระบบที่ควรค่าสำหรับการดำรงอยู่ อย่าลืมว่าแทมมี่มีสมองที่สมบูรณ์แบบดังนั้นการใช้ฐานข้อมูลเพื่อบันทึกการสั่งซื้อกระดาษเช็ดมือเล็ก ๆ ที่ไม่มีใครสังเกตได้ว่าดีที่สุด เรามุ่งเน้นเป็นระบบที่มีความสำคัญจริง ๆ เช่นการรับคนจ่ายตรงเวลาตอบสนองต่อเหตุฉุกเฉิน ฯลฯ มันเป็นประโยชน์อย่างมากที่การใช้ WITH (NOLOCK) เป็นที่เข้าใจกันโดยผู้คนเขียนโปรแกรมระบบใด ๆ ที่มีคุณค่า เมื่อบุคคลสามารถทำงานได้ดีกว่าฐานข้อมูลให้พิจารณานำเสนอทรัพยากรเหล่านั้นใหม่
WonderWorker

10

2 เซ็นต์ของฉัน - มันสมเหตุสมผลที่จะใช้WITH (NOLOCK) เมื่อคุณต้องการสร้างรายงาน ณ จุดนี้ข้อมูลจะไม่เปลี่ยนแปลงมากนัก & คุณไม่ต้องการล็อกระเบียนเหล่านั้น


2
ฉันคิดว่า WITH (NoLOCK) จะดีกว่าถ้าคุณไม่สนใจการเปลี่ยนแปลงในปัจจุบัน
Abdul Saboor

9

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

สำหรับบันทึกทางการเงิน (และบันทึกอื่น ๆ เกือบทั้งหมดในแอปพลิเคชั่นส่วนใหญ่) nolockจะสร้างความหายนะเนื่องจากคุณสามารถอ่านข้อมูลย้อนหลังจากบันทึกที่กำลังเขียนและไม่ได้รับข้อมูลที่ถูกต้อง


5
น่าแปลกที่เมื่อทำงานกับข้อมูลทางการเงินนี่ไม่ใช่ปัญหา เนื่องจากแถวจะไม่ถูกแก้ไขและบัญชีจะถูกกระทบยอดในตอนท้ายของวันการอ่านข้อมูลปลอมชั่วคราวจึงไม่ทำอะไรเลย
Jonathan Allen

8

ฉันเคยเรียก "ชุดต่อไป" สำหรับสิ่งที่ต้องทำ ไม่สำคัญว่าในกรณีนี้จะเป็นรายการที่แน่นอนและฉันมีผู้ใช้จำนวนมากที่เรียกใช้แบบสอบถามนี้


1
เราทำสิ่งที่คล้ายกันเพื่อนำเสนองานพื้นหลังด้วยคิวงานที่ต้องทำ หากเมื่อถึงระเบียนหนึ่งจะไม่มีอยู่ / ตรงกับเกณฑ์การเลือกอีกต่อไปมันจะย้ายไปยังระเบียนถัดไป
TripeHound

7

ใช้ nolock เมื่อคุณโอเคกับข้อมูล "สกปรก" ซึ่งหมายความว่า nolock ยังสามารถอ่านข้อมูลที่อยู่ในกระบวนการของการแก้ไขและ / หรือข้อมูลที่ไม่มีข้อผูกมัด

โดยทั่วไปแล้วไม่ใช่ความคิดที่ดีที่จะใช้ในสภาพแวดล้อมการทำธุรกรรมที่สูงและนั่นคือสาเหตุที่ไม่ใช่ตัวเลือกเริ่มต้นสำหรับการสืบค้น


3
ครั้งเดียวที่คุณต้องการมันอยู่ในสภาพแวดล้อมการทำธุรกรรมสูง หากตารางของคุณไม่มีการใช้งานเป็นส่วนใหญ่คุณจะไม่ได้อะไรเลย
Jonathan Allen

7

ฉันใช้กับ (nolock) คำใบ้โดยเฉพาะในฐานข้อมูล SQLServer 2000 ที่มีกิจกรรมสูง ฉันไม่แน่ใจว่าเป็นสิ่งจำเป็นใน SQL Server 2005 อย่างไรก็ตาม ฉันเพิ่งเพิ่มคำใบ้นั้นใน SQL Server 2000 ตามคำร้องขอของ DBA ของลูกค้าเพราะเขาสังเกตเห็นการล็อกเรคคอร์ด SPID จำนวนมาก

ทั้งหมดที่ฉันสามารถพูดได้คือการใช้คำใบ้ไม่ได้ทำให้เราเจ็บปวดและดูเหมือนว่าจะทำให้ปัญหาการล็อคแก้ได้เอง DBA ที่ลูกค้านั้นยืนยันว่าเราใช้คำใบ้

ยังไงก็ตามฐานข้อมูลที่ฉันจัดการด้วยนั้นเป็นระบบ back-end ของระบบเคลมทางการแพทย์ระดับองค์กรดังนั้นเราจึงพูดถึงบันทึกนับล้านและตาราง 20+ ในการเข้าร่วมจำนวนมาก ฉันมักจะเพิ่มคำแนะนำ WITH (nolock) สำหรับแต่ละตารางในการเข้าร่วม (ยกเว้นว่ามันเป็นตารางที่ได้มาซึ่งในกรณีนี้คุณไม่สามารถใช้คำใบ้นั้นได้)


1
SQL Server 2005 ได้เพิ่ม "row versioning" ซึ่งน่าจะช่วยลดความต้องการ nolocks ลงได้อย่างมาก เราเพิ่งอัปเกรดและไม่ได้ฝึกอบรม DBA ของเราเพื่อหยุดใช้งาน
Jonathan Allen

5

คำตอบที่ง่ายที่สุดคือคำถามง่าย ๆ - คุณต้องการผลลัพธ์ที่จะทำซ้ำได้หรือไม่? ถ้าใช่แล้ว NOLOCKS ไม่เหมาะสมในทุกสถานการณ์

หากคุณไม่ต้องการความสามารถในการทำซ้ำ nolocks อาจมีประโยชน์โดยเฉพาะถ้าคุณไม่สามารถควบคุมกระบวนการทั้งหมดที่เชื่อมต่อกับฐานข้อมูลเป้าหมาย

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