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

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

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

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

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

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

ABORTED: Too much contention on these documents. Please try again.

ลักษณะการทำงานจะขึ้นอยู่กับประเภทของการควบคุมการเกิดขึ้นพร้อมกันเมื่อตัดสินใจว่าจะทำให้การดำเนินการใดล้มเหลวหรือหน่วงเวลา

การควบคุมการเกิดขึ้นพร้อมกัน

โหมดการเกิดขึ้นพร้อมกันเป็นตัวเลือกฐานข้อมูลที่กำหนดค่าได้ Cloud Firestore รองรับโหมดการเกิดขึ้นพร้อมกันต่อไปนี้

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

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

    เมื่อธุรกรรมล็อกเอกสาร การดำเนินการเขียนอื่นๆ จะต้องรอให้ธุรกรรมปล่อยการล็อก ธุรกรรมจะได้รับการล็อกตามลำดับเวลา

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

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

ค่าเริ่มต้นของโหมดการเกิดขึ้นพร้อมกัน

ค่าเริ่มต้นสำหรับรุ่น Standard คือ PESSIMISTIC ค่าเริ่มต้นสำหรับรุ่น Enterprise คือ OPTIMISTIC อย่างไรก็ตาม ลักษณะการทำงานจะขึ้นอยู่กับประเภทของไลบรารีของไคลเอ็นต์ด้วย ดังนี้

  • SDK บนอุปกรณ์เคลื่อนที่ / เว็บใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองในแง่ดี 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 ใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองในแง่ร้ายและสันนิษฐานว่ามีเวลาในการตอบสนองต่ำและการเชื่อมต่อกับฐานข้อมูลที่เชื่อถือได้

การแยกข้อมูลแบบอนุกรม

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

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

ในระบบที่มีระดับการแยกข้อมูลต่ำ การดำเนินการอ่านภายในธุรกรรมอาจอ่านข้อมูลที่ไม่ถูกต้องจากการเปลี่ยนแปลงที่ยังไม่ได้คอมมิตในการดำเนินการพร้อมกัน

การแยกข้อมูลแบบอนุกรมกำหนดระดับการแยกข้อมูลสูงสุด การแยกข้อมูลแบบอนุกรมหมายความว่า

  • คุณสามารถสันนิษฐานได้ว่าฐานข้อมูลจะดำเนินการธุรกรรมแบบอนุกรม
  • ธุรกรรมจะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงที่ยังไม่ได้คอมมิตในการดำเนินการพร้อมกัน

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

Cloud Firestore รับประกันการแยกข้อมูลแบบอนุกรมของธุรกรรม ธุรกรรมใน Cloud Firestore จะทำให้เป็นอนุกรมและแยกข้อมูลตามเวลาคอมมิต

การแยกข้อมูลแบบอนุกรมตามเวลาคอมมิต

Cloud Firestore กำหนดเวลาคอมมิตให้กับแต่ละธุรกรรม ซึ่งแสดงถึง จุดเดียวในเวลา เมื่อ Cloud Firestore คอมมิตการเปลี่ยนแปลงของธุรกรรม ลงในฐานข้อมูล คุณสามารถสันนิษฐานได้ว่าการอ่านและการเขียนทั้งหมดภายในธุรกรรม จะเกิดขึ้นตรงเวลาคอมมิต

การดำเนินการธุรกรรมจริงต้องใช้เวลาช่วงหนึ่ง การดำเนินการธุรกรรมจะเริ่มก่อนเวลาคอมมิต และการดำเนินการหลายรายการอาจเกิดขึ้นพร้อมกัน Cloud Firestore จะรักษาการแยกข้อมูลแบบอนุกรม และรับประกันสิ่งต่อไปนี้

  • Cloud Firestore จะคอมมิตธุรกรรมตามลำดับเวลาคอมมิต
  • Cloud Firestore จะแยกธุรกรรมจากการดำเนินการพร้อมกัน ที่มีเวลาคอมมิตในภายหลัง

ในกรณีที่มีการแย่งชิงข้อมูลระหว่างการดำเนินการพร้อมกัน Cloud Firestore จะใช้การควบคุมการเกิดขึ้นพร้อมกันแบบมองในแง่ดีและมองในแง่ร้ายเพื่อแก้ปัญหาการแย่งชิง

การแยกข้อมูลภายในธุรกรรม

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

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

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