ฉันควรล็อคแถวในฐานข้อมูลคลาวด์ของฉันในขณะที่พวกเขากำลังแก้ไขโดยผู้ใช้


12

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

ฉันคิดถึงการเพิ่มเขตข้อมูลis_lockedและlock_timestampตาราง DB เมื่อผู้ใช้เริ่มแก้ไขรายการแถวจะเปลี่ยนis_lockedเป็นจริงและตั้งค่าการประทับเวลาล็อคเป็นเวลาปัจจุบัน ฉันจะมีเวลาบ้างที่จะล็อค (ตัวอย่างเช่น 5 นาที) หากบุคคลอื่นพยายามแก้ไขรายการพวกเขาจะได้รับข้อความแจ้งว่ารายการนั้นถูกล็อคและเมื่อการล็อคหมดอายุโดยอัตโนมัติ หากผู้ใช้เดินออกไปในขณะที่แก้ไขล็อคจะหมดอายุโดยอัตโนมัติหลังจากช่วงเวลาสั้น ๆ และเมื่อผู้ใช้จะได้รับการเตือนว่าล็อคหมดอายุและถูกบังคับให้รีสตาร์ทการแก้ไขหลังจากที่มีการรีเฟรชข้อมูล

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

(ข้อกังวลอื่น ๆ ที่ฉันมีคือ 2 คนได้รับการล็อคสำหรับไอเท็มเดียวกัน แต่ฉันเชื่อว่าเป็นเงื่อนไขการแข่งขันที่ฉันพอใจ)


1
"ข้อกังวลอีกอย่างหนึ่งของฉันคือ 2 คนได้รับการล็อคสำหรับไอเท็มเดียวกัน แต่ฉันเชื่อว่าเป็นเงื่อนไขการแข่งขันที่ฉันพอใจ" - การใช้ธุรกรรมฐานข้อมูลรอบ ๆ การซื้อล็อคควรป้องกันเงื่อนไขการแข่งขันดังกล่าว
จูลส์

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

ความจริงที่ว่าแอปพลิเคชันของคุณเป็นแอปพลิเคชันเดสก์ท็อป ( ไคลเอนต์ไขมัน ) ไม่ได้สร้างความแตกต่างมากนัก สามารถออกแบบในลักษณะเดียวกับแอพพลิเคชั่นเซิร์ฟเวอร์หลายอินสแตนซ์ที่มีความพร้อมใช้งานสูง
Hosam Aly

คำตอบ:


19

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

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

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

คุณไม่ได้ระบุ 'cloud DB' ที่คุณใช้ คุณควรตรวจสอบคุณสมบัติของสิ่งนั้นเพื่อดูว่ามีคุณสมบัติในตัวหรือไม่ก่อนที่จะนำโซลูชันของคุณไปใช้

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


นี่เป็นคำตอบที่มีประโยชน์มาก คุณช่วยอธิบายได้ไหมว่าทำไมการล็อกโลกในแง่ร้ายจึงไม่เกิดขึ้นเมื่อมีโอกาส "การชน" เล็ก ๆ น้อย ๆ เป็นเพราะหมดจดไปยังฐานข้อมูลเพื่อเริ่มแก้ไขหรือเพราะความซับซ้อนพิเศษหรือเหตุผลอื่น ๆ ? ขอบคุณ!
yitzih

3
@yitzih บางคนอ่านข้อเสนอแนะ: ฟาวเลอร์, et al, รูปแบบของสถาปัตยกรรม Enterprise Application มีคำถามทั้งหมดของบทนี้พร้อมการอภิปรายที่ดีเกี่ยวกับตัวเลือกและเหตุผลทั้งหมดในการเลือก
จูลส์

2
@Jimmy - คำตอบของคุณใช้ได้ ในบางกรณีการรายงานข้อผิดพลาดกลับมาไม่เพียงพอ พิจารณากรณีและปัญหาเมื่อผู้ใช้ใช้เวลาไม่กี่นาทีในการอัพเดทบันทึก ในกรณีดังกล่าวความล้มเหลวเพียงอย่างเดียวอาจไม่ดีพอผู้ใช้อาจต้องการรวมการเปลี่ยนแปลงบนเครื่องบินกับผู้ใช้รายอื่น ฉันควรจะกล่าวว่าการล็อคในแง่ดีอาจต้องมีการแก้ไขข้อขัดแย้งขึ้นอยู่กับความต้องการของคุณ
Jon Raynor

3
เป็นมูลค่าการกล่าวขวัญว่าการล็อคในแง่ร้ายเป็นเรื่องง่ายมากที่จะอธิบายให้กับลูกค้า หากคุณเขียนข้อความที่ลูกค้าไม่สามารถเข้าถึงบันทึกได้เนื่องจากขณะนี้กำลังมีการแก้ไขโดยที่อื่นลูกค้าทั้งคู่เข้าใจดีและยอมรับโดยทั่วไป หากคุณบอกลูกค้าหลังจากบันทึกการบันทึกนั้นเป็นไปไม่ได้เพราะมันได้รับการปรับปรุงโดยผู้ใช้รายอื่นแล้ว 7/10 ลูกค้าจะหงุดหงิดและ / หรือคาดว่าจะมีคำอธิบายสำหรับพฤติกรรมของโปรแกรมแปลก ๆ นี้
Neil

2
@ Neil นั่นเป็นความจริงและฉันคิดว่าบ่อยครั้งที่ทำไมการใช้การล็อกในแง่ร้ายเมื่อมองโลกในแง่ดีเหมาะสมกว่า บ่อยครั้งที่เวิร์กโฟลว์ทำให้ไม่น่าเป็นไปได้มากที่มีการชนกัน
JimmyJames

0

จากคำตอบของ @ JimmyJamesเราสามารถเห็นได้ว่าคำถามนี้เกี่ยวกับประสบการณ์การใช้งานของผู้ใช้อย่างไร

ทุกอย่างขึ้นอยู่กับบริบท ต้องใช้เวลาและความพยายามในการอัปเดตระเบียนนานเท่าใด ผู้ใช้หลายคนต้องการอัพเดตเอกสารเดียวกันบ่อยแค่ไหน?

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

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

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

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

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