ความสามารถในการเรียงลำดับและการแยกธุรกรรม

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

ธุรกรรมและการแย่งชิงข้อมูล

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

การช่วงชิงข้อมูล
เมื่อมีการดำเนินการตั้งแต่ 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 จะใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองโลกในแง่ดีและมองโลกในแง่ร้ายเพื่อแก้ไขการช่วงชิงข้อมูล

การแยกภายในธุรกรรม

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

ปัญหาเกี่ยวกับการแย่งชิงข้อมูล

ดูข้อมูลเพิ่มเติมเกี่ยวกับการช่วงชิงข้อมูลและวิธีแก้ไขได้ที่หน้าการแก้ปัญหา