ความสัมพันธ์ที่แน่นอนระหว่างธุรกรรมฐานข้อมูลและการล็อกคืออะไร


16

นี่เป็นคำถามถ่อมใจที่ถามในวิญญาณของการเพิ่มความรู้ของฉัน; กรุณาอ่อนโยนในการตอบสนองของคุณ

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

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

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

นั่นคือมันเกิดขึ้นกับฉันว่าเพื่อให้การทำธุรกรรมเป็นปรมาณูและโดดเดี่ยวนั้นจะต้องมีการล็อค การล็อคทรานแซคชั่นซ่อนเร้นจากทรานแซคชันนี้เป็นการล็อกแบบเดียวกับที่ฐานข้อมูลต่างๆให้ฉันเข้าถึงผ่านการสร้างเช่นSELECT FOR UPDATEหรือLOCKคำสั่งที่ชัดเจน? หรือแนวคิดทั้งสองนี้แตกต่างอย่างสิ้นเชิง?

อีกครั้งฉันขอโทษสำหรับnaïvetéของคำถามนี้ ฉันมีความสุขที่จะชี้ไปที่แหล่งข้อมูลพื้นฐานเพิ่มเติม

คำตอบ:


12

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

ใช่. หากนั่นไม่เป็นความจริง 'การล็อค' ของคุณเองจะถูก จำกัด ไว้ที่ 'การล็อค' อื่น ๆ ที่คล้ายกันเท่านั้นและจะไม่โต้ตอบกับการล็อคของเครื่องยนต์ ดังนั้นคุณจะล็อคแถวในตารางเพื่อให้แอปพลิเคชันอื่นไม่สามารถล็อคในลักษณะเดียวกันได้ แต่กลไกการล็อคของคุณจะถูกละเว้น ความหมายเหล่านี้ไม่ค่อยเป็นที่ต้องการ ส่วนใหญ่เวลาที่แอปพลิเคชันล็อกแถวหมายถึง 'ล็อคกับวิธีการเข้าถึง / แก้ไข' บันทึก Side ว่ากลไกการล็อคที่มีอย่างเคร่งครัดเฉพาะของโปรแกรมทำอยู่เพราะพวกเขามีประโยชน์ ยกตัวอย่างเช่น SQL Server มีโปรแกรมล็อค

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

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

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


บางทีคุณสามารถเพิ่มเกี่ยวกับการควบคุมภาวะพร้อมกันในแง่ดี
ypercubeᵀᴹ

Aha! ตอนนี้เรากำลังพูดถึง อันที่จริงที่ซุ่มซ่อนที่ด้านหลังของใจของฉันเป็นMVCC ขอบคุณสำหรับคำตอบที่พูดชัดถ้อยชัดคำอ้างอิงที่ดีและใช้เวลาในการขุดคำถามของฉัน
Laird Nelson

3

พื้นหลังบางส่วนก่อนตอบคำถามของคุณ:

หมายเหตุ: สิ่งนี้เกี่ยวข้องกับ Microsoft SQL Server - RDBMS ........

  • ในแง่ง่ายมากธุรกรรมเป็นลำดับของงานที่ต้องดำเนินการเป็นหน่วยโลจิคัลเดียวอย่างครบถ้วนและต้องรักษาคุณสมบัติของกรด
  • RDBMS ใด ๆ จะต้องจัดเตรียม "สิ่งอำนวยความสะดวกการล็อก" ที่สามารถใช้เพื่อทำธุรกรรมให้เสร็จสมบูรณ์ได้โดยมีการแยกการทำธุรกรรมและความทนทานของมัน สิ่งนี้ทำให้มั่นใจได้ถึงความสมบูรณ์ทางกายภาพของฐานข้อมูล
  • สิ่งสำคัญที่สุดคือโดยค่าเริ่มต้น - ธุรกรรมถูกจัดการที่ระดับการเชื่อมต่อ ดังนั้นเมื่อการทำธุรกรรมเริ่มต้นในการเชื่อมต่อคำสั่ง T-SQL ทั้งหมด (S / I / U / D) ที่ดำเนินการบนการเชื่อมต่อนั้นเป็นส่วนหนึ่งของการทำธุรกรรมจนกว่าการทำธุรกรรมจะสิ้นสุดลง ( MARSจัดการแตกต่างกัน)

กลับไปที่คำถามของคุณ:

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

ใช่. ซึ่งหมายความว่าคุณต้องระมัดระวังในการกำหนดลำดับของข้อมูลที่จะแก้ไขและจะทำให้ฐานข้อมูลอยู่ในสถานะที่สอดคล้องกัน กล่าวอีกนัยหนึ่งการดำเนินการ DML ของคุณควรปล่อยให้ฐานข้อมูลอยู่ในสถานะที่สอดคล้องซึ่ง จำกัด อยู่ในกฎเกณฑ์ทางธุรกิจขององค์กรของคุณ ยัง RDBMS (ที่นี่ SQL Server) สามารถบังคับใช้ความสมบูรณ์ทางกายภาพของการทำธุรกรรม

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

การล็อกทรานแซคชันนี้เริ่มต้นโดยการทำธุรกรรมซ่อนอยู่แบบเดียวกันกับการล็อกที่ฐานข้อมูลต่าง ๆ ให้ฉันเข้าถึงผ่านโครงสร้างเช่น SELECT FOR UPDATE หรือคำสั่ง LOCK อย่างชัดเจนหรือไม่?

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

อ้างอิงที่ดีบางอย่าง:


2

ฉันจะบอกว่าการทำธุรกรรมเป็นส่วนหนึ่งของฐานข้อมูล "อินเทอร์เฟซ" ในแง่หนึ่งก็คือคุณในฐานะนักพัฒนาตัดสินใจว่าจะเริ่มต้นสิ้นสุดสิ่งที่ต้องทำภายในขอบเขตของการทำธุรกรรม ฯลฯ ล็อคตามที่ฉันเห็นพวกเขา และใช้สำหรับการซิงโครไนซ์การเข้าถึงวัตถุที่แตกต่างกัน ในกรณีส่วนใหญ่เครื่องยนต์จะตัดสินใจเองว่าควรล็อคไว้นานเท่าใด มีการล็อคระดับระบบจำนวนมากที่ไม่สามารถจัดการได้โดยตรง (เช่นเครื่องยนต์อาจล็อคพื้นที่หน่วยความจำบางอย่าง) แม้ว่าจะมาถึงการล็อค DML หลายคนก็เกิดขึ้นหลังฉาก (ตัวอย่างเช่นเพื่อให้แน่ใจว่า Referential Integrity Oracle และเท่าที่ฉันจำได้ SQLServer อาจวางล็อคในแถวที่สอดคล้องกันในตารางต้นแบบถ้าบันทึกใหม่ถูกแทรกลงใน ตารางรายละเอียด) อันเป็นผลมาจากคำสั่ง DML ที่ออกภายในธุรกรรม

เมื่อพูดถึงธุรกรรมคุณสามารถคาดหวังพฤติกรรมที่สอดคล้องกันมากขึ้นหรือน้อยลงจาก RDMS ใด ๆ ที่อ้างว่าเป็นไปตาม SQL และธุรกรรมที่สนับสนุน แต่เมื่อมาถึงการล็อคผู้ขายเกือบทุกรายจะใช้กลยุทธ์และคำศัพท์ที่แตกต่างกัน ส่วนที่พบบ่อยใน RMDS ทั้งหมดเท่าที่ฉันสามารถบอกได้ว่าการทำรายการพร้อมกันระหว่างธุรกรรมนั้นถูกกำหนดโดยระดับการแยกในขณะที่การล็อกพร้อมกันระหว่างล็อคนั้นถูกควบคุมโดยประเภทการล็อก (shared, exclusive, etc)

เพื่อสรุปล็อคเป็นกลไกระดับต่ำเพื่อควบคุมความมั่นคงของวัตถุและการทำงานพร้อมกัน ล็อคสามารถออกในระหว่างการดำเนินการคำสั่ง SQL ขึ้นอยู่กับการใช้งานในการแยกธุรกรรมระดับเอ็นจิ้นอาจทำการล็อกประเภทต่าง ๆ บนวัตถุที่ได้รับผลกระทบ มีคำสั่งจำนวน จำกัด ที่พร้อมใช้งานสำหรับการล็อกด้วยตนเอง ( SELECT FOR UPDATE, LOCK) การล็อก DML สามารถเลื่อนระดับได้ (ขึ้นอยู่กับ RDMS ตัวอย่างเช่นใน SQLServer row-> page-> partition-> table) ล็อกยังสามารถออกได้โดยเอ็นจิ้นฐานข้อมูลในระหว่างการเริ่มต้นการเชื่อมต่อการสำรองข้อมูลการคืนค่าขั้นตอน / ทริกเกอร์ / ฟังก์ชั่น / การคอมไพล์ซ้ำ ฯลฯ การเริ่มต้นการปิดเครื่อง ฯลฯ

ฉันไม่แน่ใจว่าสิ่งนั้นตอบคำถามของคุณหรือไม่ แต่ฉันหวังว่ามันสมเหตุสมผล


ขอบคุณสำหรับความคิดเห็นของคุณ. คุณอยู่ใกล้ที่สุดแน่นอน ฉันยังคงพยายามที่จะดูว่าการทำธุรกรรมจะดำเนินการในแง่ของการล็อคที่ใช้โดยพูดชัดเจนLOCKหรือSELECT FOR UPDATEงบหรือผ่านกลไกอื่น ๆ
Laird Nelson

เท่าที่ฉันรู้ตัวBEGIN TRANSACTIONเองไม่มีปัญหาล็อค การล็อคจะปรากฏขึ้นหลังจาก DML ภายในธุรกรรม
a1ex07

ชี้แจง - ฉันหมายถึงBEGIN TRANSACTIONตัวเองไม่ได้สร้างล็อค DML; ในความเป็นจริงมันควรออกล็อคภายในเพราะต้องจัดสรรทรัพยากรเพิ่มรายการในตารางระบบ (ถ้ามี) ที่ถือธุรกรรมที่ใช้งาน ฯลฯ
a1ex07

1

ฉันจะใช้ศัพท์แสงของ SQL Server แต่แนวคิดควรจะเหมือนกันสำหรับผู้ขายรายอื่น:

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

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


ขอบคุณสำหรับความคิดเห็นของคุณ. เท่าที่ฉันรู้ แต่คำถามของฉันยังคง: เมื่อเปิดธุรกรรมนั้นการแยกสำเร็จโดยการล็อคกุญแจของตัวเองหรือไม่? ถ้าเป็นเช่นนั้นล็อคเหล่านั้นเป็นล็อคประเภทเดียวกันที่ฉันสามารถรับได้อย่างชัดเจนหรือไม่ หรือการทำธุรกรรมบรรลุแยกจากกันด้วยวิธีการอื่น ๆ ?
Laird Nelson

2
ใช่มันเป็นกลไกเดียวกัน การแยกทำได้โดยใช้การล็อกในทั้งสองโหมดการล็อคเดียวกันกับที่คุณสามารถรับได้อย่างชัดเจน ความแตกต่างคือถ้าคุณไม่ได้เปิดธุรกรรมอย่างชัดเจนล็อคจะถูกปล่อยออกมาเมื่อคำสั่งเสร็จสิ้นในขณะที่การทำธุรกรรมอย่างชัดเจนล็อคจะถูกเก็บไว้จนกว่าคุณจะยอมรับ (ไม่ถูกต้อง 100% เนื่องจากระดับการแยก แต่นั่นคือ แนวคิดทั่วไป)
Matan Yungman

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

@LairdNelson นั่นคือSnapshot Isolation levelสำหรับ SQL Server มีอยู่แล้ว แต่ไม่ใช่กลไกเริ่มต้นสำหรับการทำงานพร้อมกัน มันเป็นค่าเริ่มต้นสำหรับ Oracle หรือ Postgresql แม้ว่า IIRC
Marian

0

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

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

  • ** อะตอมมิกซิตี้
  • ความมั่นคง
  • ความเหงา
  • ความคงทน **

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

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

ความสอดคล้องหมายความว่าคุณรับประกันได้ว่าข้อมูลของคุณจะสอดคล้องกัน; ข้อ จำกัด ที่คุณมีกับข้อมูลที่เกี่ยวข้องจะไม่ถูกละเมิด

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

ความทนทานหมายความว่าเมื่อการทำธุรกรรมเสร็จสิ้นจะรับประกันได้ว่าการเปลี่ยนแปลงทั้งหมดได้ถูกบันทึกไว้ในสื่อที่ทนทาน (เช่นฮาร์ดดิสก์) และความจริงที่ว่าการทำธุรกรรมนั้นเสร็จสิ้นแล้วจะถูกบันทึกเช่นเดียวกัน

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


ขอบคุณสำหรับความคิดเห็นของคุณ อย่างน้อยฉันก็รับรู้ถึงคุณสมบัติของกรด สิ่งที่ฉันยังไม่ชัดเจนคือ: ธุรกรรมใช้ ACID โดยใช้การล็อกชนิดเดียวกับที่ฉันสามารถใช้โดยตรงผ่านLOCKคำสั่งที่ชัดเจนหรือพวกมันใช้กลไกอื่นหรือไม่?
Laird Nelson

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