ในภาษาอังกฤษธรรมดาสิ่งที่เป็นข้อเสียและข้อดีของการใช้
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
ในแบบสอบถามสำหรับ. NET แอปพลิเคชันและบริการรายงานแอปพลิเคชัน
ในภาษาอังกฤษธรรมดาสิ่งที่เป็นข้อเสียและข้อดีของการใช้
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
ในแบบสอบถามสำหรับ. NET แอปพลิเคชันและบริการรายงานแอปพลิเคชัน
คำตอบ:
ระดับการแยกนี้ช่วยให้การอ่านสกปรก ธุรกรรมหนึ่งอาจเห็นการเปลี่ยนแปลงที่ไม่ได้รับการยอมรับจากการทำธุรกรรมอื่น ๆ
เพื่อรักษาระดับสูงสุดของการแยกโดยปกติ DBMS จะได้รับการล็อคข้อมูลซึ่งอาจทำให้สูญเสียการทำงานพร้อมกันและค่าใช้จ่ายการล็อคสูง ระดับการแยกนี้ผ่อนคลายคุณสมบัตินี้
คุณอาจต้องการตรวจสอบบทความ WikipediaREAD UNCOMMITTED
สำหรับตัวอย่างและอ่านเพิ่มเติม
คุณอาจสนใจตรวจสอบบทความบล็อกของ Jeff Atwood เกี่ยวกับวิธีที่เขาและทีมของเขาจัดการกับปัญหาการหยุดชะงักในช่วงแรก ๆ ของ Stack Overflow อ้างอิงจากเจฟ:
แต่
nolock
อันตรายไหม คุณสามารถอ่านข้อมูลที่ไม่ถูกต้องด้วยการread uncommitted
เปิดหรือไม่ ใช่ในทางทฤษฎี คุณจะพบปัญหาการขาดแคลนนักบินอวกาศสถาปัตยกรรมฐานข้อมูลไม่มีที่เริ่มต้นวางวิทยาศาสตร์กรดกับคุณและทุกคนnolock
แต่ดึงสัญญาณเตือนไฟไหม้อาคารเมื่อคุณบอกพวกเขาว่าคุณต้องการที่จะลอง เป็นจริง: ทฤษฎีนั้นน่ากลัว แต่นี่คือสิ่งที่ฉันคิด: "ในทางทฤษฎีไม่มีความแตกต่างระหว่างทฤษฎีและการปฏิบัติในทางปฏิบัติมี"ฉันจะไม่แนะนำให้ใช้
nolock
เป็น "ดีสำหรับสิ่งที่คุณ" แก้ไขน้ำมันงูสำหรับฐานข้อมูลใด ๆ ที่อาจมีปัญหาการหยุดชะงัก คุณควรลองวิเคราะห์สาเหตุของปัญหาก่อนแต่ในทางปฏิบัติการเพิ่ม
nolock
คำค้นหาที่คุณรู้ว่าเป็นเรื่องง่ายและอ่านอย่างเดียวนั้นไม่เคยนำไปสู่ปัญหา ... ตราบใดที่คุณรู้ว่าคุณกำลังทำอะไรอยู่
หนึ่งทางเลือกให้กับระดับที่คุณอาจต้องการที่จะต้องพิจารณาคือREAD UNCOMMITTED
READ COMMITTED SNAPSHOT
การอ้างเจฟฟ์อีกครั้ง:
สแนปชอตอาศัยวิธีการติดตามการเปลี่ยนแปลงข้อมูลใหม่ทั้งหมด ... มากกว่าการเปลี่ยนแปลงเชิงตรรกะเพียงเล็กน้อยโดยเซิร์ฟเวอร์จะต้องจัดการกับข้อมูลที่แตกต่างกัน เมื่อเปิดใช้งานวิธีการติดตามการเปลี่ยนแปลงข้อมูลใหม่มันจะสร้างสำเนาหรือภาพรวมของการเปลี่ยนแปลงข้อมูลทุกครั้ง ด้วยการอ่านสแนปชอตเหล่านี้แทนการใช้ข้อมูลสดในช่วงเวลาของการช่วงชิงจึงไม่จำเป็นต้องใช้ Shared Locks ในการอ่านอีกต่อไปและประสิทธิภาพของฐานข้อมูลโดยรวมอาจเพิ่มขึ้น
READ UNCOMMITTED
อาจทำให้คุณอ่านแถวสองครั้งหรือพลาดทั้งแถวก็ได้ หากการแบ่งหน้าเกิดขึ้นขณะที่คุณกำลังอ่านคุณสามารถพลาดข้อมูลทั้งหมดได้ WITH(NOLOCK)
ควรใช้เฉพาะในกรณีที่ความแม่นยำของผลลัพธ์ไม่สำคัญ
สิ่งนี้มีประโยชน์ในการดูความคืบหน้าของการสืบค้นแบบแทรกแบบยาวทำการประมาณคร่าวๆ (เช่นCOUNT(*)
หรือแบบคร่าวๆSUM(*)
) เป็นต้น
กล่าวอีกนัยหนึ่งผลลัพธ์ที่ได้จากการอ่านที่สกปรกกลับมาได้ดีตราบใดที่คุณปฏิบัติต่อพวกมันเป็นค่าประมาณและไม่ต้องทำการตัดสินใจที่สำคัญใด ๆ
กรณีการใช้งานที่ชื่นชอบสำหรับฉันread uncommited
คือการแก้ไขข้อบกพร่องบางอย่างที่เกิดขึ้นในการทำธุรกรรม
เริ่มซอฟต์แวร์ของคุณภายใต้ดีบักเกอร์ในขณะที่คุณกำลังก้าวผ่านบรรทัดของรหัสมันจะเปิดธุรกรรมและปรับเปลี่ยนฐานข้อมูลของคุณ ในขณะที่รหัสหยุดทำงานคุณสามารถเปิดตัววิเคราะห์แบบสอบถามตั้งค่าระดับการแยกแบบอ่านที่ไม่ได้รับการตอบรับและสร้างคิวรีเพื่อดูว่าเกิดอะไรขึ้น
นอกจากนี้คุณยังสามารถใช้เพื่อดูว่าขั้นตอนการรันนานหรือติดตั้งหรือปรับปรุงฐานข้อมูลของคุณอย่างถูกต้อง
เป็นการดีถ้า บริษัท ของคุณชอบทำขั้นตอนการจัดเก็บที่ซับซ้อนมากเกินไป
ข้อดีคือมันสามารถเร็วขึ้นในบางสถานการณ์ ข้อเสียคือผลลัพธ์อาจผิด (ข้อมูลที่ยังไม่ได้ส่งคืน) และไม่มีการรับประกันว่าผลลัพธ์จะสามารถทำซ้ำได้
หากคุณใส่ใจในความถูกต้องอย่าใช้สิ่งนี้
ข้อมูลเพิ่มเติมเกี่ยวกับMSDN :
ใช้การอ่านที่สกปรกหรือการล็อกระดับการแยก 0 ซึ่งหมายความว่าไม่มีการล็อกที่ใช้ร่วมกันและไม่มีการล็อคแบบเอกสิทธิ์เฉพาะบุคคล เมื่อตั้งค่าตัวเลือกนี้เป็นไปได้ที่จะอ่านข้อมูลที่ไม่มีข้อผูกมัดหรือสกปรก ค่าในข้อมูลสามารถเปลี่ยนแปลงได้และแถวสามารถปรากฏหรือหายไปในชุดข้อมูลก่อนสิ้นสุดการทำธุรกรรม ตัวเลือกนี้มีผลเช่นเดียวกับการตั้งค่า NOLOCK บนตารางทั้งหมดในคำสั่ง SELECT ทั้งหมดในการทำธุรกรรม นี่เป็นข้อ จำกัด ที่น้อยที่สุดของสี่ระดับการแยก
select
คำสั่งไม่ต้องรอที่จะได้รับการล็อคที่ใช้ร่วมกันในทรัพยากรที่ถูกล็อคโดยการทำธุรกรรมอื่น ๆ
จะใช้READ UNCOMMITTED
เมื่อไร?
ดี : รายงานรวมขนาดใหญ่แสดงยอดรวมที่เปลี่ยนแปลงตลอดเวลา
มีความเสี่ยงเกือบทุกอย่าง
ข่าวดีก็คือรายงานส่วนใหญ่จะอยู่ในหมวดหมู่ที่ดีเท่านั้น
ตกลงที่จะใช้มัน:
ซึ่งครอบคลุมส่วนใหญ่ของแผนก Business Intelligence ที่จะทำใน SSRS ข้อยกเว้นคืออะไรที่มีเครื่องหมาย $ อยู่ข้างหน้า หลายคนบัญชีเงินด้วยความกระตือรือร้นมากกว่าที่ใช้กับตัวชี้วัดหลักที่เกี่ยวข้องที่จำเป็นในการให้บริการลูกค้าและสร้างเงินนั้น (ฉันโทษนักบัญชี)
เมื่อมีความเสี่ยง
รายงานใด ๆ ที่ลงไปถึงระดับรายละเอียด หากจำเป็นต้องมีรายละเอียดดังกล่าวโดยปกติจะหมายความว่าทุกแถวจะเกี่ยวข้องกับการตัดสินใจ ในความเป็นจริงหากคุณไม่สามารถดึงชุดย่อยขนาดเล็กโดยไม่ปิดกั้นอาจเป็นเพราะเหตุผลที่ดีที่กำลังถูกแก้ไข
ข้อมูลทางประวัติศาสตร์. มันไม่ค่อยสร้างความแตกต่างในทางปฏิบัติ แต่ในขณะที่ผู้ใช้เข้าใจว่าข้อมูลที่เปลี่ยนแปลงตลอดเวลาไม่สามารถสมบูรณ์แบบพวกเขาไม่รู้สึกเหมือนกันกับข้อมูลแบบคงที่ การอ่านที่สกปรกจะไม่เจ็บที่นี่ แต่การอ่านซ้ำสองครั้งสามารถทำได้ การเห็นว่าคุณไม่ควรมีบล็อกข้อมูลคงที่อยู่แล้วทำไมจึงเสี่ยง
เกือบทุกอย่างที่ฟีดแอปพลิเคชันซึ่งมีความสามารถในการเขียน
เมื่อแม้แต่สถานการณ์ OK ก็ไม่เป็นไร
NOLOCK
กับสิ่งเหล่านั้นได้เลยread uncommitted
สำหรับเว็บแอปพลิเคชันเมื่อผู้ใช้เห็นกริด UI บางส่วนที่ความแม่นยำของข้อมูลไม่สำคัญนัก ผู้ใช้ต้องการภาพรวมอย่างรวดเร็วว่ามีระเบียนใดบ้างและอาจมีการแบ่งหน้าการเรียงลำดับและการกรอง เฉพาะเมื่อผู้ใช้คลิกปุ่มแก้ไขจากนั้นฉันพยายามอ่านระเบียนล่าสุดที่มีระดับการแยกที่เข้มงวดมากขึ้น วิธีการดังกล่าวไม่ควรจะดีกว่าในแง่ของประสิทธิภาพ?
select item from things with (UPDLOCK)
คุณสามารถจัดการว่าด้วยการเริ่มต้นการทำธุรกรรมการเรียกข้อมูลเช่น ใส่ไทม์เอาต์อย่างรวดเร็วไว้ที่นั่นเพื่อที่ว่าถ้ามันไม่สามารถล็อคได้อย่างรวดเร็วมันจะบอกผู้ใช้ว่ามันกำลังถูกแก้ไข ที่จะทำให้คุณปลอดภัยไม่เพียง แต่จากผู้ใช้ แต่นักพัฒนา ปัญหาเฉพาะที่นี่คือคุณต้องเริ่มคิดเกี่ยวกับการหมดเวลาและวิธีจัดการกับ UI
เกี่ยวกับการรายงานเราจะใช้มันในแบบสอบถามการรายงานทั้งหมดของเราเพื่อป้องกันการสืบค้นจากฐานข้อมูล เราสามารถทำได้เพราะเราดึงข้อมูลประวัติไม่ใช่ข้อมูลแบบไมโครวินาที
ใช้ READ_UNCOMMITTED ในสถานการณ์ที่แหล่งที่มาไม่น่าจะเปลี่ยนแปลงได้อย่างมาก
อย่าใช้ READ_UNCOMMITTED เมื่อคุณรู้ว่า souce อาจมีการเปลี่ยนแปลงระหว่างการดึงข้อมูล
READ UNCOMMITTED
ได้
READ UNCOMMITTED
สถานการณ์ส่วนใหญ่เมื่อข้อมูลของคุณถูกใช้อย่างแข็งขันและคุณต้องการลดภาระบนเซิร์ฟเวอร์เพื่อหลีกเลี่ยงการหยุดชะงักและการย้อนกลับการทำธุรกรรมเพียงเพราะผู้ใช้บางคน รีเฟรช "ในหน้าเว็บที่มี DataGrid ผู้ใช้ที่ดูบันทึกจำนวนมากในเวลาเดียวกันโดยทั่วไปจะไม่สนใจอะไรมากหากข้อมูลนั้นล้าสมัยหรืออัปเดตบางส่วน เมื่อผู้ใช้กำลังจะแก้ไขบันทึกคุณอาจต้องการให้ข้อมูลที่ถูกต้องที่สุดแก่เขา / เธอ
สิ่งนี้จะทำให้คุณอ่านสกปรกและแสดงธุรกรรมที่ยังไม่ได้ทำ นั่นคือคำตอบที่ชัดเจนที่สุด ฉันไม่คิดว่ามันเป็นความคิดที่ดีที่จะใช้สิ่งนี้เพื่อเร่งการอ่านของคุณ มีวิธีอื่นในการทำเช่นนั้นหากคุณใช้การออกแบบฐานข้อมูลที่ดี
มันน่าสนใจที่จะทราบว่าอะไรไม่เกิดขึ้น READ UNCOMMITTED ไม่เพียง แต่ละเว้นการล็อคตารางอื่น ๆ นอกจากนี้ยังไม่ก่อให้เกิดการล็อคใด ๆ ในตัวเอง
พิจารณาว่าคุณกำลังสร้างรายงานขนาดใหญ่หรือคุณกำลังย้ายข้อมูลออกจากฐานข้อมูลของคุณโดยใช้คำสั่ง SELECT ขนาดใหญ่และซับซ้อน นี่จะทำให้การล็อคที่ใช้ร่วมกันที่อาจเพิ่มระดับเป็นล็อคตารางที่แชร์ในช่วงเวลาของการทำธุรกรรมของคุณ ธุรกรรมอื่น ๆ อาจอ่านจากตาราง แต่การปรับปรุงเป็นไปไม่ได้ นี่อาจเป็นความคิดที่ดีถ้าฐานข้อมูลการผลิตเนื่องจากการผลิตอาจหยุดอย่างสมบูรณ์
หากคุณใช้ READ UNCOMMITTED คุณจะไม่ตั้งค่าการล็อคที่ใช้ร่วมกันบนโต๊ะ คุณอาจได้รับผลจากการทำธุรกรรมใหม่บางอย่างหรือคุณอาจไม่ได้ขึ้นอยู่กับตารางที่ข้อมูลถูกแทรกและระยะเวลาที่การทำธุรกรรม SELECT ของคุณอ่าน คุณอาจได้รับข้อมูลเดียวกันสองครั้งหากมีการแบ่งหน้า (ข้อมูลจะถูกคัดลอกไปยังตำแหน่งอื่นในไฟล์ข้อมูล)
ดังนั้นหากเป็นสิ่งสำคัญมากสำหรับคุณที่สามารถแทรกข้อมูลในขณะที่ทำการเลือกของคุณการอ่าน UNCOMMITTED อาจเข้าท่า คุณต้องพิจารณาว่ารายงานของคุณอาจมีข้อผิดพลาดบางอย่าง แต่ถ้ารายงานของคุณนั้นขึ้นอยู่กับแถวหลายล้านแถวและมีเพียงไม่กี่แห่งเท่านั้นที่ได้รับการอัปเดตในขณะที่เลือกผลลัพธ์ ธุรกรรมของคุณอาจล้มเหลวด้วยกันเนื่องจากอาจไม่รับประกันความเป็นหนึ่งเดียวของแถว
วิธีที่ดีกว่าโดยสิ้นเชิงคือการใช้ SNAPSHOT ISOLATION LEVEL แต่แอปพลิเคชันของคุณอาจต้องมีการปรับเปลี่ยนเพื่อใช้งานนี้ ตัวอย่างหนึ่งคือหากแอปพลิเคชันของคุณใช้การล็อกแบบเอกสิทธิ์เฉพาะบุคคลในแถวเพื่อป้องกันไม่ให้ผู้อื่นอ่านและเข้าสู่โหมดแก้ไขใน UI SNAPSHOT ISOLATION LEVEL ระดับนั้นมาพร้อมกับประสิทธิภาพที่สูง (โดยเฉพาะบนดิสก์) แต่คุณอาจเอาชนะมันได้ด้วยการโยนฮาร์ดแวร์ลงบนปัญหา :)
คุณอาจพิจารณากู้คืนข้อมูลสำรองของฐานข้อมูลเพื่อใช้สำหรับการรายงานหรือโหลดข้อมูลลงในคลังข้อมูล
สามารถใช้สำหรับตารางอย่างง่ายตัวอย่างเช่นในตารางตรวจสอบแบบแทรกเท่านั้นซึ่งไม่มีการอัพเดตแถวที่มีอยู่และไม่มี fk ไปยังตารางอื่น เม็ดมีดเป็นเม็ดมีดแบบง่าย ๆ ซึ่งไม่มีโอกาสย้อนกลับเล็กน้อย
ฉันใช้ READ UNCOMMITTED เสมอ มันรวดเร็วด้วยปัญหาน้อยที่สุด เมื่อใช้ตัวแยกอื่น ๆ คุณจะพบเจอปัญหาการบล็อกบางอย่าง
ตราบใดที่คุณใช้ฟิลด์การเพิ่มอัตโนมัติและให้ความสำคัญกับส่วนแทรกเพิ่มมากขึ้นคุณก็สามารถบอกลาการบล็อกปัญหาได้
คุณสามารถทำข้อผิดพลาดกับ READ UNCOMMITED แต่ตามจริงแล้วมันเป็นเรื่องง่ายมากที่จะทำให้แน่ใจว่าส่วนแทรกของคุณนั้นมีการพิสูจน์อย่างสมบูรณ์ ส่วนแทรก / อัพเดตที่ใช้ผลลัพธ์จากตัวเลือกเป็นสิ่งเดียวที่คุณต้องระวัง (ใช้ READ COMMITTED ที่นี่หรือตรวจสอบให้แน่ใจว่าการอ่านที่สกปรกจะไม่ทำให้เกิดปัญหา)
ดังนั้นไปที่ Dirty Reads (พิเศษสำหรับรายงานขนาดใหญ่) ซอฟต์แวร์ของคุณจะทำงานได้ราบรื่นขึ้น ...
Committed
แทรกและอัปเดต สำหรับปัญหาอื่น ๆ เขายังแสดงให้เห็นถึงการตระหนักถึงปัญหาการแบ่งหน้าโดยกล่าวถึงการใช้คีย์การเพิ่มอัตโนมัติ ฉันเห็นด้วยกับเขาว่าการรายงานสดเกือบทุกเรื่องที่มนุษย์อ่านสามารถทนต่อความคลาดเคลื่อนเล็กน้อยในตำแหน่งทศนิยมสุดท้าย ฉันเห็นด้วยว่ามันเป็นเรื่องราวที่แตกต่างกันสำหรับรายการที่มีรายละเอียดหรือข้อมูลที่กำหนดให้เป็นเครื่องอ่านและแปลงและ Clive