หน้านี้จะอธิบายการแย่งชิงข้อมูลธุรกรรม ความสามารถในการจัดลำดับ และการแยกข้อมูล ดูตัวอย่างโค้ดธุรกรรมได้ที่ธุรกรรมและการเขียนแบบกลุ่มแทน
ธุรกรรมและการแย่งชิงข้อมูล
เพื่อให้ธุรกรรมสำเร็จ เอกสารที่ดึงมาจากการดำเนินการอ่านต้องไม่มีการแก้ไขโดยการดำเนินการนอกธุรกรรม หากการดำเนินการอื่นพยายามเปลี่ยนแปลงเอกสารรายการใดรายการหนึ่ง การดำเนินการนั้นจะเข้าสู่สถานะการช่วงชิงข้อมูลกับธุรกรรม
- การช่วงชิงข้อมูล
- เมื่อมีการดำเนินการตั้งแต่ 2 รายการขึ้นไปที่แข่งขันกันเพื่อควบคุมเอกสารเดียวกัน ตัวอย่างเช่น ธุรกรรมหนึ่งอาจกำหนดให้เอกสารต้องสอดคล้องกันในขณะที่การดำเนินการที่เกิดขึ้นพร้อมกันพยายามอัปเดตค่าในช่องของเอกสารนั้น
Cloud Firestore แก้ไขการแย่งชิงข้อมูลโดยการหน่วงเวลาหรือทำให้การดำเนินการอย่างใดอย่างหนึ่งล้มเหลว ไลบรารีของไคลเอ็นต์ Cloud Firestore จะลองทำธุรกรรมที่ล้มเหลวเนื่องจากการแย่งชิงข้อมูลอีกครั้งโดยอัตโนมัติ หลังจากลองใหม่ครบตามจำนวนครั้งที่กำหนดแล้ว การดำเนินการธุรกรรมจะล้มเหลวและแสดงข้อความแสดงข้อผิดพลาดต่อไปนี้
ABORTED: Too much contention on these documents. Please try again.
เมื่อตัดสินใจว่าจะให้การดำเนินการใดล้มเหลวหรือล่าช้า ลักษณะการทำงานจะขึ้นอยู่กับประเภทของการควบคุมการเกิดขึ้นพร้อมกัน
การควบคุมการเกิดขึ้นพร้อมกัน
โหมดการเกิดขึ้นพร้อมกันเป็นตัวเลือกฐานข้อมูลที่กำหนดค่าได้ Cloud Firestore รองรับโหมดการทำงานพร้อมกันต่อไปนี้
PESSIMISTIC: การควบคุมการเกิดขึ้นพร้อมกันแบบ Pessimistic จะถือว่ามีแนวโน้มที่จะเกิดการแย่งชิงข้อมูล ธุรกรรมแบบ Pessimistic จะใช้การล็อกฐานข้อมูลเพื่อป้องกันไม่ให้การดำเนินการอื่นๆ แก้ไขข้อมูลเมื่อใช้การควบคุมการเกิดขึ้นพร้อมกันแบบ Pessimistic ธุรกรรมจะล็อกเอกสารที่อ่าน การล็อกเอกสารของธุรกรรมจะบล็อกธุรกรรมอื่นๆ การเขียนแบบกลุ่ม และการเขียนที่ไม่ใช่ธุรกรรมไม่ให้เปลี่ยนแปลงเอกสารนั้น ธุรกรรมจะปลดล็อกเอกสารเมื่อคอมมิต นอกจากนี้ยังปลดล็อกหากหมดเวลาหรือดำเนินการไม่สำเร็จไม่ว่าด้วยเหตุผลใดก็ตาม
เมื่อธุรกรรมล็อกเอกสาร การดำเนินการเขียนอื่นๆ ต้องรอให้ธุรกรรมปลดล็อก ธุรกรรมจะได้รับล็อกตามลำดับเวลา
OPTIMISTIC: การควบคุมการเกิดขึ้นพร้อมกันในแง่ดีจะถือว่าการช่วงชิงข้อมูลไม่น่าจะเกิดขึ้นหรือการคงการล็อกฐานข้อมูลไว้ไม่มีประสิทธิภาพ ธุรกรรมแบบ Optimistic ไม่ใช้การล็อกฐานข้อมูลเพื่อบล็อกการดำเนินการอื่นๆ ไม่ให้เปลี่ยนแปลงข้อมูลเมื่อใช้การควบคุมการเกิดขึ้นพร้อมกันในแง่ดี ธุรกรรมจะติดตามเอกสารทั้งหมดที่คุณอ่านภายในธุรกรรม ธุรกรรมจะดำเนินการเขียนให้เสร็จสมบูรณ์ก็ต่อเมื่อไม่มีเอกสารใดเปลี่ยนแปลงในระหว่างการดำเนินการธุรกรรม หากเอกสารมีการเปลี่ยนแปลง ตัวแฮนเดิลธุรกรรมจะลองทำธุรกรรมอีกครั้ง หากธุรกรรมไม่ได้รับผลลัพธ์ที่ชัดเจนหลังจากลองใหม่ 2-3 ครั้ง ธุรกรรมจะล้มเหลวเนื่องจากการช่วงชิงข้อมูล
ค่าเริ่มต้นของโหมดการทำงานพร้อมกัน
ค่าเริ่มต้นสำหรับรุ่น Standard คือ PESSIMISTIC ค่าเริ่มต้นสำหรับรุ่น Enterprise คือ OPTIMISTIC อย่างไรก็ตาม ลักษณะการทำงานยังขึ้นอยู่กับประเภทของไลบรารีของไคลเอ็นต์ด้วย ดังนี้
- SDK สำหรับอุปกรณ์เคลื่อนที่ / เว็บใช้การควบคุมการเกิดขึ้นพร้อมกันแบบ Optimistic SDK บนอุปกรณ์เคลื่อนที่และเว็บจะทำงานโดยไม่ขึ้นอยู่กับการตั้งค่านี้ เนื่องจากจะจำลองการเกิดขึ้นพร้อมกันในแง่ดีเสมอ
- ไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์ใช้การควบคุมการเกิดขึ้นพร้อมกันของการตั้งค่าฐานข้อมูล
โหมดการดูพร้อมกัน
เรียกใช้คำสั่ง
gcloud firestore databases describe
เพื่อดูโหมดการเกิดขึ้นพร้อมกันฝั่งเซิร์ฟเวอร์ของฐานข้อมูล
gcloud firestore databases describe \
--project=PROJECT_ID \
--database=DATABASE_ID
เปลี่ยนโหมดการทำงานพร้อมกัน
เรียกใช้คำสั่ง
gcloud firestore databases update
เพื่อเปลี่ยนโหมดการเกิดขึ้นพร้อมกันฝั่งเซิร์ฟเวอร์ของฐานข้อมูล
gcloud firestore databases update \
--project=PROJECT_ID \
--database=DATABASE_ID \
--concurrency-mode=CONCURRENCY_MODE
โดยที่
- CONCURRENCY_MODE คือ
PESSIMISTICหรือOPTIMISTIC - PROJECT_ID คือรหัสของโปรเจ็กต์ Google Cloud
- DATABASE_ID คือรหัสของฐานข้อมูล Cloud Firestore
การแย่งชิงข้อมูลใน SDK บนอุปกรณ์เคลื่อนที่/เว็บ
SDK สำหรับอุปกรณ์เคลื่อนที่และเว็บจะจำลองธุรกรรมการเกิดขึ้นพร้อมกันในเชิงบวกโดยใช้เงื่อนไขเบื้องต้นในการเขียนในเวอร์ชันเอกสาร การจำลองนี้จะเกิดขึ้นไม่ว่าการตั้งค่าโหมดการเกิดขึ้นพร้อมกันของฐานข้อมูลจะเป็นอย่างไรก็ตาม SDK บนอุปกรณ์เคลื่อนที่และเว็บไม่ได้ใช้ฟีเจอร์ธุรกรรมในตัว ดังนั้นแม้ว่าจะกำหนดค่าโหมดการทำงานพร้อมกันของฐานข้อมูลเป็น PESSIMISTIC ไคลเอ็นต์มือถือก็ยังคงทำงานในลักษณะที่มองโลกในแง่ดี
SDK บนอุปกรณ์เคลื่อนที่/เว็บใช้การควบคุมการเกิดขึ้นพร้อมกันในเชิงบวก เนื่องจากสามารถทำงานในสภาพแวดล้อมที่มีเวลาในการตอบสนองสูงและการเชื่อมต่อเครือข่ายที่ไม่เสถียร การล็อกเอกสารในสภาพแวดล้อมที่มีเวลาในการตอบสนองสูงจะทำให้เกิดความล้มเหลวในการแย่งชิงข้อมูลมากเกินไป
การช่วงชิงข้อมูลในไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์
ไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์ (C#, Go, Java, Node.js, PHP, Python, Ruby) ใช้ฟีเจอร์ธุรกรรมในตัว ธุรกรรมเหล่านี้ใช้การตั้งค่าโหมดการเกิดขึ้นพร้อมกันระดับฐานข้อมูล และค่าเริ่มต้นจะขึ้นอยู่กับรุ่น ดังนี้
รุ่น Enterprise จะใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองโลกในแง่ดีโดยค่าเริ่มต้นเพื่อรองรับการดำเนินการที่สแกนคอลเล็กชันทั้งหมด การควบคุมการเกิดขึ้นพร้อมกันในแง่ดีช่วยหลีกเลี่ยงการดำเนินการสแกนที่ล็อกเอกสารจำนวนมาก
รุ่น Standard ใช้การควบคุมการเกิดขึ้นพร้อมกันแบบ Pessimistic และถือว่ามีเวลาในการตอบสนองต่ำและการเชื่อมต่อกับฐานข้อมูลที่เชื่อถือได้
การแยกแบบเรียงอันดับได้
การช่วงชิงข้อมูลระหว่างธุรกรรมมีความเกี่ยวข้องอย่างใกล้ชิดกับระดับการแยกฐานข้อมูล ระดับการแยกของฐานข้อมูลจะอธิบายว่าระบบจัดการกับความขัดแย้งระหว่างการดำเนินการที่เกิดขึ้นพร้อมกันได้ดีเพียงใด ความขัดแย้งเกิดจากข้อกำหนดของฐานข้อมูลต่อไปนี้
- ธุรกรรมต้องมีข้อมูลที่ถูกต้องและสอดคล้องกัน
- ฐานข้อมูลจะดำเนินการพร้อมกันเพื่อใช้ทรัพยากรอย่างมีประสิทธิภาพ
ในระบบที่มีระดับการแยกต่ำ การดำเนินการอ่านภายในธุรกรรมอาจอ่านข้อมูลที่ไม่ถูกต้องจากการเปลี่ยนแปลงที่ยังไม่ได้คอมมิตในการดำเนินการที่เกิดขึ้นพร้อมกัน
การแยกแบบอนุกรมจะกำหนดระดับการแยกสูงสุด การแยกแบบเรียงอันดับได้หมายความว่า
- คุณสามารถสันนิษฐานได้ว่าฐานข้อมูลจะดำเนินการธุรกรรมเป็นชุด
- ธุรกรรมจะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงที่ไม่ได้คอมมิตในการดำเนินการที่เกิดขึ้นพร้อมกัน
การรับประกันนี้ต้องคงอยู่แม้ว่าฐานข้อมูลจะดำเนินการธุรกรรมหลายรายการพร้อมกันก็ตาม ฐานข้อมูลต้องใช้การควบคุมการเกิดขึ้นพร้อมกันเพื่อแก้ไขข้อขัดแย้งที่จะทำให้การรับประกันนี้เป็นโมฆะ
Cloud Firestore รับประกันการแยกธุรกรรมที่ทำให้เป็นอนุกรมได้ ธุรกรรมใน Cloud Firestore จะได้รับการจัดเรียงเป็นอนุกรมและแยกตามเวลาคอมมิต
การแยกแบบเรียงอันดับได้ตามเวลาคอมมิต
Cloud Firestore กำหนดเวลาคอมมิตให้กับธุรกรรมแต่ละรายการซึ่งแสดงถึงจุดเวลาเดียว เมื่อ Cloud Firestore คอมมิตการเปลี่ยนแปลงของธุรกรรมไปยังฐานข้อมูล คุณจะถือว่าการอ่านและการเขียนทั้งหมดภายในธุรกรรมเกิดขึ้น ณ เวลาที่คอมมิตพอดี
การทำธุรกรรมจริงต้องใช้เวลาสักระยะหนึ่ง การดำเนินการธุรกรรมจะเริ่มต้นก่อนเวลาคอมมิต และการดำเนินการหลายรายการอาจทับซ้อนกัน Cloud Firestore รองรับการแยกแบบเรียงอันดับได้และรับประกันว่า
- Cloud Firestore จะคอมมิตธุรกรรมตามลำดับเวลาคอมมิต
- Cloud Firestore จะแยกธุรกรรมออกจากการดำเนินการที่เกิดขึ้นพร้อมกันซึ่งมีเวลาคอมมิตในภายหลัง
ในกรณีที่เกิดการช่วงชิงข้อมูลระหว่างการดำเนินการที่เกิดขึ้นพร้อมกัน Cloud Firestore จะใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองโลกในแง่ดีและมองโลกในแง่ร้ายเพื่อแก้ไขการช่วงชิงข้อมูล
การแยกภายในธุรกรรม
การแยกธุรกรรมยังมีผลกับการดำเนินการเขียนภายในธุรกรรมด้วย การค้นหาและการอ่านภายในธุรกรรมจะไม่เห็นผลลัพธ์ของการเขียนก่อนหน้าภายในธุรกรรมนั้น แม้ว่าคุณจะแก้ไขหรือลบเอกสารภายในธุรกรรม แต่การอ่านเอกสารทั้งหมดในธุรกรรมนั้นจะแสดงเอกสารเวอร์ชัน ณ เวลาที่คอมมิต ก่อนการดำเนินการเขียนของธุรกรรม การดำเนินการอ่านจะไม่แสดงผลใดๆ หากเอกสารไม่มีอยู่ ณ ขณะนั้น
ปัญหาเกี่ยวกับการแย่งชิงข้อมูล
ดูข้อมูลเพิ่มเติมเกี่ยวกับการช่วงชิงข้อมูลและวิธีแก้ไขได้ที่หน้าการแก้ปัญหา