0Pricing
SQL Academy · บทเรียน

การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง

เปรียบเทียบรูปแบบ SELECT ... FOR UPDATE (แบบระมัดระวัง) กับ version-column / WHERE updated_at = ? (แบบมองโลกในแง่ดี)

การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

กลยุทธ์การทำงานพร้อมกันสองแบบ

  • แบบป้องกันล่วงหน้า — ล็อกแถวเมื่ออ่าน ทำให้ผู้อื่นไม่สามารถเปลี่ยนแปลงแถวได้
  • แบบตรวจสอบภายหลัง — ไม่ล็อก แต่ตรวจสอบตอนอัปเดตว่าแถวยังไม่เปลี่ยนแปลง

แบบป้องกันล่วงหน้า: SELECT ... FOR UPDATE

ล็อกตอนนี้ แล้วเขียนภายหลัง:

BEGIN;
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;
-- other transactions cannot lock or update this row
-- compute new balance...
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;

FOR SHARE

การล็อกเพื่ออ่าน ผู้อื่นยังอ่านได้แต่เขียนไม่ได้:

SELECT * FROM orders WHERE id = 1 FOR SHARE;
-- others can SELECT FOR SHARE but cannot UPDATE

ข้อดีและข้อเสียของการป้องกันล่วงหน้า

ข้อดี: ทำความเข้าใจได้ง่าย ไม่ต้องลองใหม่
ข้อเสีย: ลดการทำงานพร้อมกัน และอาจทำให้เกิดการรอการล็อกกับภาวะล็อกตาย

แบบตรวจสอบภายหลัง: คอลัมน์รุ่น

อ่านพร้อมรุ่น แล้วเขียนโดยใช้ WHERE version = expected:

BEGIN;
SELECT id, balance, version FROM accounts WHERE id = 1;
-- compute new balance...
UPDATE accounts
   SET balance = ?, version = version + 1
WHERE id = 1 AND version = ?;
-- check rows affected: 0 means someone else updated, retry

แบบตรวจสอบภายหลังด้วย updated_at

แนวคิดเดียวกัน โดยใช้ updated_at แทนคอลัมน์รุ่นที่กำหนดขึ้นโดยเฉพาะ:

UPDATE accounts
   SET balance = ?, updated_at = NOW()
WHERE id = ? AND updated_at = ?;

-- If updated_at has changed in the meantime, 0 rows affected — retry.

ข้อดีและข้อเสียของการตรวจสอบภายหลัง

ข้อดี: ทำงานพร้อมกันได้มาก ไม่ต้องรอ
ข้อเสีย: การเขียนอาจล้มเหลวและต้องใช้ตรรกะสำหรับลองใหม่ ความขัดแย้งจะปรากฏเมื่อถึงเวลา UPDATE เท่านั้น

เมื่อใดควรเลือกการป้องกันล่วงหน้า

เหมาะสำหรับ:

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

เมื่อใดควรเลือกการตรวจสอบภายหลัง

เหมาะสำหรับ:

  • งานที่เน้นการอ่านและมีความขัดแย้งเกิดขึ้นน้อย
  • API แบบไร้สถานะที่ไคลเอนต์ถือแถวไว้ระหว่างคำขอ
  • การแก้ไขบนอุปกรณ์เคลื่อนที่หรือขณะออฟไลน์ แล้วซิงค์ภายหลัง

แบบผสม: FOR UPDATE NOWAIT

ลองล็อก หากถูกล็อกอยู่ให้ล้มเหลวทันทีและให้ผู้ใช้ลองใหม่:

SELECT * FROM accounts WHERE id = 1 FOR UPDATE NOWAIT;
-- ERROR if someone else holds it — user sees a friendly retry message

การล็อกเชิงคำแนะนำ

การล็อกระดับแอปที่ไม่ผูกกับแถวใดแถวหนึ่ง:

SELECT pg_try_advisory_xact_lock(hashtext('order:42'));
-- True if you got the lock, false otherwise — useful for cross-row coordination.

อย่าลืมสร้างดัชนีให้เป้าหมายการล็อก

การใช้ FOR UPDATE โดยไม่มีดัชนีในคอลัมน์ WHERE อาจล็อกแถวม​​ากกว่าที่คาดไว้ (จะล็อกแถวที่สแกน ไม่ใช่เฉพาะแถวที่ตรงเงื่อนไข)

การหมดเวลารอการล็อก

กำหนด lock_timeout เพื่อหลีกเลี่ยงการรอตลอดไป:

SET lock_timeout = '5s';
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;
-- ERROR if lock not acquired in 5 seconds

สรุปทบทวน

การป้องกันล่วงหน้าจะล็อกแถว ส่วนการตรวจสอบภายหลังจะตรวจสอบเมื่อเขียน

  • แบบป้องกันล่วงหน้า: FOR UPDATE — เรียบง่ายแต่ลดการทำงานพร้อมกัน
  • แบบตรวจสอบภายหลัง: คอลัมน์รุ่น — ทำงานพร้อมกันได้มากกว่าแต่ต้องลองใหม่
  • เลือกตามลักษณะงาน และผสมผสานกันเมื่อจำเป็น

แบบทดสอบสั้น ๆ

การลดจำนวนสินค้าคงคลังในพาณิชย์อิเล็กทรอนิกส์มีการแย่งใช้งานสูง กลยุทธ์การล็อกใดโดยทั่วไปปลอดภัยกว่า

คำถามที่พบบ่อย

บทเรียน “การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง”

เปรียบเทียบรูปแบบ SELECT ... FOR UPDATE (แบบระมัดระวัง) กับ version-column / WHERE updated_at = ? (แบบมองโลกในแง่ดี) คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่

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

บทเรียน “การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม

ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คุณสมบัติ ACID และความผิดปกติ
  2. ระดับการแยก: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
  3. เดดล็อก: การตรวจจับและการหลีกเลี่ยง
  4. การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง
← กลับไปที่ SQL Academy