การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง
เปรียบเทียบรูปแบบ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คุณสมบัติ ACID และความผิดปกติ
- ระดับการแยก: READ COMMITTED, REPEATABLE READ, SERIALIZABLE
- เดดล็อก: การตรวจจับและการหลีกเลี่ยง
- การล็อกแบบมองโลกในแง่ดีเทียบกับแบบระมัดระวัง