ماڈیول اسباق (3/4)
لاکنگ اور اپ ڈیٹ کے لیے منتخب کریں۔
یہ سمجھنا کہ ڈیٹا بیس ایک ہی ٹرمینل پر تنہائی میں کیسے کام کرتا ہے آسان ہے... انتظار نہ کریں، میں پہلے ہی کہہ چکا ہوں!
کبھی کبھی "ایٹمک اپ ڈیٹس" (جیسے stock = stock - 1) کافی نہیں ہوتے ہیں۔
آئیے تصور کریں کہ آپ کو یہ چیک کرنا ہوگا کہ آیا صارف کے پاس 50€ مالیت کا سامان خریدنے کے لیے کافی بیلنس ہے:
SELECT balance FROM users WHERE id = 1;- JS: اگر بیلنس < 50 ہے، تو انہیں بلاک کریں!
- بصورت دیگر چیک آؤٹ کے ساتھ آگے بڑھیں...
- کٹوتی چلائیں! (اور یہاں آپ کو ایک صارف ملتا ہے جس نے، مرحلہ 2 پر چیک کی توثیق کرتے ہوئے، ایک اور متوازی کو ہٹا دیا جو ان کے اکاؤنٹ میں جل گیا اور اب آپ صفر سے نیچے جا رہے ہیں!)
اپ ڈیٹ کے لیے واضح لاکنگ
FOR UPDATE کو SELECT کے آخر میں شامل کرنا جادوئی طور پر آپ کے معصوم پڑھے کو اگلے COMMIT تک دوسرے کلائنٹس کے خلاف مہر بند لاک میں بدل دیتا ہے۔ کوئی اور ان مخصوص منتخب قطاروں پر اپ ڈیٹ (یا ہم آہنگ پڑھنے کے لیے اپ ڈیٹ) نہیں کر سکے گا جب تک کہ آپ یہ فیصلہ نہ کر لیں کہ ان کے ساتھ کیا کرنا ہے!
BEGIN;
-- If id=3 had already been locked by T1, T2 will sit in perpetual loading on this "read"
-- frozen in place, before receiving the raw data, until T1 runs COMMIT freeing everyone!
SELECT balance
FROM users
WHERE id = 3
FOR UPDATE;
-- at this point our Node JS instance lives with the guarantee, knowing for certain that NO ONE ELSE in the world has
-- manipulated (nor been able to read with intent to alter) that balance while we complete the application logic
UPDATE users SET balance = balance - 50 WHERE id = 3;
COMMIT;یہاں تک کہ FOR SHARE ہے جو دوسرے قارئین کو اسٹیٹ ریڈز کو مسدود کیے بغیر (اگر بیس لاک پر ہے) پڑھنا جاری رکھنے دیتا ہے، لیکن اس وقت تک کسی بھی ممکنہ اپ ڈیٹ کو اس وقت تک روکتا ہے جب تک کہ آپ کمٹمنٹ نہ کریں۔ اگرچہ ترمیم کے لیے، ہمیشہ خصوصی لاکنگ شق کی بری طاقت کا استعمال کریں:
خود ہی آزمائیں۔
ایک عام ٹائم اسکوپڈ ٹرانزیکشن کھولیں اور خصوصی طور پر پروڈکٹ ID=5 کے پڑھنے کو لاک کریں۔\nدو قدمی استفسار چلائیں:\n1۔ ٹرانزیکشن کھولیں (BEGIN)\n2. 'مصنوعات' سے استفسار کریں کہ ID 5 کے لیے پوری قطار کو حاصل کریں اس گارنٹی کے ساتھ کہ کوئی بھی اسے تبدیل نہیں کرے گا، 'فار اپ ڈیٹ' کے آپشن کو منسلک کر کے۔
اشارہ دکھائیں۔
شروع کریں؛، نئی لائن، منتخب کریں * پروڈکٹس سے جہاں id = 5 اپ ڈیٹ کے لیے؛
3 کوششوں کے بعد حل دستیاب ہے۔
بعض اوقات لین دین تباہ کن ادوار (تعطل یا لامحدود انتظار) کے لیے معلق رہتا ہے۔\nاس کو روکنے کے لیے آپ ڈیٹابیس کو اس وقت ترک کرنے کا حکم دے سکتے ہیں جب قطار فوری طور پر دستیاب نہ ہو: آخر میں NOWAIT کا استعمال کرتے ہوئے، جس کی وجہ سے SQL سرور کا استثنیٰ JS میں واپس باؤنس ہو جائے گا تاکہ ہمیشہ کے لیے لٹکائے بغیر کوشش کی جا سکے اور ID=UPFORUNZ کے لیے زمرہ کا انتخاب کریں۔ ابھی
اشارہ دکھائیں۔
منتخب کریں * زمرہ جات سے جہاں id = 1 اپ ڈیٹ کے لیے NOWAIT؛
3 کوششوں کے بعد حل دستیاب ہے۔