InterSystems IRIS DBMS ڊيٽا کي محفوظ ڪرڻ لاءِ دلچسپ جوڙجڪ کي سپورٽ ڪري ٿو - گلوبل. بنيادي طور تي، اهي ملٽي ليول ڪنجيون آهن جن ۾ ٽرانزيڪشن جي صورت ۾ مختلف اضافي سامان، ڊيٽا جي وڻن، تالون ۽ ان جي پنهنجي ObjectScript ٻولي کي ٽريڪ ڪرڻ لاءِ تيز ڪارناما آهن.
مضمونن جي سيريز ۾ گلوبلز بابت وڌيڪ پڙهو ”گلوبلز ڊيٽا محفوظ ڪرڻ لاءِ خزانا تلوارون آهن“:
مون کي دلچسپي ورتي ته ڪيئن ٽرانزيڪشن کي گلوبلن ۾ لاڳو ڪيو وڃي ٿو، اتي ڪهڙيون خاصيتون آهن. سڀ کان پوء، هي عام جدولن جي ڀيٽ ۾ ڊيٽا کي محفوظ ڪرڻ لاء هڪ مڪمل طور تي مختلف جوڙجڪ آهي. تمام گھٽ سطح.
جيئن ته تعلقي ڊيٽابيس جي نظريي مان معلوم ٿئي ٿو، ٽرانزيڪشن جو سٺو عمل لازمي طور تي ضرورتن کي پورو ڪرڻ گهرجي. :
الف - ايٽمي (ايٽمي). ٽرانزيڪشن ۾ ڪيل سڀ تبديليون يا سڀ ڪجھ به رڪارڊ ٿيل نه آهن.
ج - تسلسل. هڪ ٽرانزيڪشن مڪمل ٿيڻ کان پوء، ڊيٽابيس جي منطقي حالت اندروني طور تي هڪجهڙائي هجڻ گهرجي. ڪيترن ئي طريقن سان هن گهرج پروگرامر جو تعلق آهي، پر SQL ڊيٽابيس جي صورت ۾ اهو پڻ غير ملڪي چابمن جو خدشو آهي.
مان - الڳ ڪرڻ. متوازي ۾ هلندڙ ٽرانزيڪشن کي هڪ ٻئي تي اثر انداز نه ٿيڻ گهرجي.
ڊي - پائيدار. ٽرانزيڪشن جي ڪامياب مڪمل ٿيڻ کان پوء، هيٺين سطح تي مسئلا (مثال طور پاور ناڪامي، مثال طور) ٽرانزيڪشن طرفان تبديل ٿيل ڊيٽا کي متاثر نه ڪرڻ گهرجي.
گلوبلز غير لاڳاپو ڊيٽا جي جوڙجڪ آهن. اهي تمام محدود هارڊويئر تي سپر تيز هلائڻ لاءِ ٺهيل هئا. اچو ته ڏسو گلوبلز ۾ ٽرانزيڪشن جي عمل کي استعمال ڪندي .
IRIS ۾ ٽرانزيڪشن کي سپورٽ ڪرڻ لاء، ھيٺيون حڪم استعمال ڪيا ويا آھن: , , .
1. ايٽمي صلاحيت
چيڪ ڪرڻ جو آسان طريقو ايٽميٽي آهي. اسان ڊيٽابيس ڪنسول مان چيڪ ڪريون ٿا.
Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMITپوء اسان اهو نتيجو ڪريون ٿا:
Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)اسان حاصل ڪريون ٿا:
1 2 3سڀ ڪجھ ٺيڪ آهي. Atomicity برقرار آهي: سڀ تبديليون رڪارڊ ٿيل آهن.
اچو ته ڪم کي پيچيده ڪريون، هڪ غلطي متعارف ڪرايو ۽ ڏسو ته ڪيئن ٽرانزيڪشن محفوظ ڪئي وئي آهي، جزوي طور تي يا نه.
اچو ته ٻيهر ايٽمي جي جانچ ڪريون:
Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3پوءِ اسان زور سان ڪنٽينر کي روڪي، ان کي لانچ ڪري ڏسنداسين.
docker kill my-irisهي حڪم لڳ ڀڳ هڪ طاقت بند ڪرڻ جي برابر آهي، ڇاڪاڻ ته اهو فوري طور تي عمل کي روڪڻ لاء SIGKILL سگنل موڪلي ٿو.
ٿي سگهي ٿو ته ٽرانزيڪشن جزوي طور تي بچايو ويو؟
WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)- نه، اهو نه بچيو آهي.
اچو ته rollback حڪم جي ڪوشش ڪريو:
Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK
WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)ڪجھ به نه بچيو آهي.
2. تسلسل
جيئن ته گلوبلز جي بنياد تي ڊيٽابيس ۾، چاٻيون پڻ گلوبلز تي ٺاهيون وينديون آهن (مان توهان کي ياد ڏيان ٿو ته هڪ گلوبل هڪ هيٺين سطح جي جوڙجڪ آهي ڊيٽا کي ذخيرو ڪرڻ لاء هڪ تعلقي جدول جي ڀيٽ ۾)، مطابقت جي گهرج کي پورو ڪرڻ لاء، ڪيئي ۾ تبديلي شامل ٿيڻ گهرجي. ساڳئي ٽرانزيڪشن ۾ عالمي تبديلي جي طور تي.
مثال طور، اسان وٽ هڪ عالمي ^شخص آهي، جنهن ۾ اسان شخصيتن کي ذخيرو ڪندا آهيون ۽ اسان TIN کي ڪيئي طور استعمال ڪندا آهيون.
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...آخري نالو ۽ پهرين نالي سان تڪڙو ڳولهڻ لاءِ، اسان ^ انڊيڪس ڪيچ ٺاهيو.
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1ڊيٽابيس لاءِ مطابقت رکڻ لاءِ، اسان کي هن طرح جي شخصيت کي شامل ڪرڻ گهرجي:
TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMITان جي مطابق، حذف ڪرڻ وقت اسان کي هڪ ٽرانزيڪشن پڻ استعمال ڪرڻ گهرجي:
TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMITٻين لفظن ۾، مطابقت جي گهرج کي پورو ڪرڻ مڪمل طور تي پروگرامر جي ڪلهن تي آهي. پر جڏهن اهو عالمي سطح تي اچي ٿو، اهو عام آهي، انهن جي گهٽ سطحي طبيعت جي ڪري.
3. اڪيلائي
هي اهو آهي جتي جهنگلي شروع ٿئي ٿي. ڪيترائي استعمال ڪندڙ هڪ ئي ڊيٽابيس تي ڪم ڪن ٿا، ساڳئي ڊيٽا کي تبديل ڪندي.
صورتحال ان جي مقابلي ۾ آهي جڏهن ڪيترائي صارف هڪ ئي وقت هڪ ئي ڪوڊ مخزن سان ڪم ڪن ٿا ۽ هڪ ئي وقت ۾ ڪيترن ئي فائلن ۾ تبديليون ڪرڻ جي ڪوشش ڪن ٿا.
ڊيٽابيس کي اهو سڀ ڪجهه حقيقي وقت ۾ ترتيب ڏيڻ گهرجي. انهي ڳالهه تي غور ڪندي ته سنگين ڪمپنين ۾ پڻ هڪ خاص ماڻهو آهي جيڪو ورزن ڪنٽرول (شاخن کي ضم ڪرڻ، تڪرار حل ڪرڻ وغيره) جو ذميوار آهي، ۽ ڊيٽابيس کي اهو سڀ ڪجهه حقيقي وقت ۾ ڪرڻ گهرجي، ڪم جي پيچيدگي ۽ صحيحيت. ڊيٽابيس ڊيزائن ۽ ڪوڊ جيڪو ان جي خدمت ڪري ٿو.
ڊيٽابيس استعمال ڪندڙن پاران ڪيل ڪمن جي معني کي سمجھي نه سگھندو آھي تڪرار کان بچڻ لاءِ جيڪڏھن اھي ساڳيا ڊيٽا تي ڪم ڪري رھيا آھن. اهو صرف هڪ ٽرانزيڪشن کي رد ڪري سگهي ٿو جيڪو ٻئي سان تڪرار ڪري ٿو، يا انهن کي ترتيب سان عمل ڪري ٿو.
هڪ ٻيو مسئلو اهو آهي ته ٽرانزيڪشن جي عمل جي دوران (هڪ واعدو کان اڳ)، ڊيٽابيس جي حالت متضاد ٿي سگهي ٿي، تنهنڪري اهو ضروري آهي ته ٻين ٽرانزيڪشن کي ڊيٽابيس جي غير مطابقت واري حالت تائين رسائي نه هوندي، جيڪا تعلقي ڊيٽابيس ۾ حاصل ڪئي وئي آهي. ڪيترن ئي طريقن سان: سنيپ شاٽ ٺاهڻ، ملٽي ورزننگ قطارون وغيره.
جڏهن متوازي طور تي ٽرانزيڪشن تي عمل ڪندي، اهو اسان لاء ضروري آهي ته اهي هڪ ٻئي سان مداخلت نه ڪن. هي اڪيلائي جي ملڪيت آهي.
SQL بيان ڪري ٿو 4 اڪيلائي جي سطح:
- اڻ پڙهيل پڙهو
- پڙهو عزم
- بار بار پڙهڻ
- سيريز ڪرڻ جي قابل
اچو ته هر سطح تي الڳ الڳ ڏسو. هر سطح تي عمل درآمد جي قيمت تقريبن تيزيء سان وڌي ٿي.
اڻ پڙهيل پڙهو - هي اڪيلائي جي سڀ کان گهٽ سطح آهي، پر ساڳئي وقت تيز ترين. ٽرانزيڪشن هڪ ٻئي پاران ڪيل تبديلين کي پڙهي سگهي ٿو.
پڙهو عزم اڪيلائي جي ايندڙ سطح آهي، جيڪو هڪ سمجهوتو آهي. ٽرانزيڪشن هڪ ٻئي جي تبديلين کي پڙھي نه سگھندا آھن وابستگي کان اڳ، پر اھي پڙھي سگھن ٿا ڪنھن به تبديليءَ کان پوءِ.
جيڪڏهن اسان وٽ هڪ ڊگهو ٽرانزيڪشن T1 آهي، جنهن دوران ٽرانزيڪشن T2، T3 ... Tn ۾ ڪم ڪيو ويو، جيڪو T1 جي ساڳي ڊيٽا سان ڪم ڪيو، پوء جڏهن T1 ۾ ڊيٽا جي درخواست ڪنداسين ته اسان هر ڀيري مختلف نتيجو حاصل ڪنداسين. هن رجحان کي غير ورجائي پڙتال سڏيو ويندو آهي.
بار بار پڙهڻ - هن اڪيلائي واري سطح ۾ اسان وٽ غير ورجائي پڙتال جو رجحان نه آهي، حقيقت اها آهي ته ڊيٽا پڙهڻ جي هر درخواست لاء، نتيجن جي ڊيٽا جو هڪ سنيپ شاٽ ٺاهيو ويندو آهي ۽ جڏهن ساڳئي ٽرانزيڪشن ۾ ٻيهر استعمال ڪيو ويندو آهي، سنيپ شاٽ مان ڊيٽا. استعمال ڪيو ويندو آهي. بهرحال، اهو ممڪن آهي ته پريتم ڊيٽا پڙهڻ لاء هن اڪيلائي جي سطح تي. هي نون قطار پڙهڻ ڏانهن اشارو ڪري ٿو جيڪي متوازي انجام ڏيڻ واري ٽرانزيڪشن طرفان شامل ڪيا ويا آهن.
سيريز ڪرڻ جي قابل - موصليت جي بلند ترين سطح. اها حقيقت اها آهي ته ڊيٽا ڪنهن به طريقي سان ٽرانزيڪشن ۾ استعمال ڪئي وئي آهي (پڙهڻ يا تبديل ڪرڻ) صرف پهرين ٽرانزيڪشن جي مڪمل ٿيڻ کان پوء ٻين ٽرانزيڪشن لاء دستياب ٿي ويندي آهي.
پهرين، اچو ته اهو معلوم ڪريون ته ڇا مکيه ٿريڊ مان ٽرانزيڪشن ۾ عملن جي اڪيلائي آهي. اچو ته 2 ٽرمينل ونڊوز کوليون.
Kill ^t
Write ^t(1)
2
TSTART
Set ^t(1)=2ڪابه اڪيلائي ناهي. هڪ ٿريڊ ڏسي ٿو ته ٻيو جيڪو ٽرانزيڪشن کوليو آهي اهو ڇا ڪري رهيو آهي.
اچو ته مختلف موضوعن جي ٽرانزيڪشن کي ڏسو ته انهن جي اندر ڇا ٿي رهيو آهي.
اچو ته 2 ٽرمينل ونڊوز کوليون ۽ 2 ٽرانزيڪشن کي متوازي ۾ کوليون.
kill ^t
TSTART
Write ^t(1)
3
TSTART
Set ^t(1)=3
متوازي ٽرانزيڪشن هڪ ٻئي جي ڊيٽا کي ڏسندا آهن. تنهن ڪري، اسان حاصل ڪيو آسان ترين، پر پڻ تيز ترين اڪيلائي سطح، UNCOMMITED پڙهو.
اصولي طور تي، اها اميد ٿي سگهي ٿي عالمين لاءِ، جنهن لاءِ ڪارڪردگي هميشه ترجيح رهي آهي.
ڇا جيڪڏهن اسان کي عالمي سطح تي آپريشن ۾ اڪيلائي جي اعليٰ سطح جي ضرورت آهي؟
هتي توهان کي سوچڻ جي ضرورت آهي ته اڪيلائي جي سطحن جي ضرورت ڇو آهي ۽ اهي ڪيئن ڪم ڪن ٿيون.
سڀ کان وڌيڪ اڪيلائي جي سطح، SERIALIZE، مطلب ته ٽرانزيڪشن جو نتيجو متوازي طور تي عمل ڪيو ويو آهي، انهن جي ترتيب واري عمل جي برابر آهي، جيڪو ٽڪرين جي غير موجودگي جي ضمانت ڏئي ٿو.
اسان اهو ڪري سگھون ٿا سمارٽ لاڪ استعمال ڪندي ObjectScript ۾، جن جا ڪيترائي مختلف استعمال آهن: توهان ڪمانڊ سان باقاعده، واڌارو، گھڻن لاڪنگ ڪري سگهو ٿا .
لوئر آئسوليشن ليول ڊيٽابيس جي رفتار کي وڌائڻ لاءِ ٺهيل ٽريڊ آف آهن.
اچو ته ڏسون ته اسان ڪيئن حاصل ڪري سگهون ٿا اڪيلائي جي مختلف سطحن کي لاڪ استعمال ڪندي.
هي آپريٽر توهان کي اجازت ڏئي ٿو ته ڊيٽا کي تبديل ڪرڻ لاءِ نه رڳو گهربل لاڪ، پر نام نهاد شيئر ٿيل لاڪ، جيڪي متوازي طور تي ڪيترن ئي موضوعن کي وٺي سگهن ٿا جڏهن انهن کي ڊيٽا پڙهڻ جي ضرورت آهي جيڪا پڙهڻ جي عمل دوران ٻين عملن طرفان تبديل نه ٿيڻ گهرجي.
روسي ۽ انگريزي ۾ ٻه-مرحلي بلاڪ ڪرڻ جي طريقن جي باري ۾ وڌيڪ معلومات:
→
→
مشڪل اهو آهي ته ٽرانزيڪشن دوران ڊيٽابيس جي حالت متضاد ٿي سگهي ٿي، پر هي متضاد ڊيٽا ٻين عملن کي نظر اچي ٿو. هن کان بچڻ لاء ڪيئن؟
لاڪ استعمال ڪندي، اسان visibility ونڊوز ٺاهينداسين جنهن ۾ ڊيٽابيس جي حالت هڪجهڙائي هوندي. ۽ اتفاق ٿيل رياست جي ڏسڻ جي اهڙين ونڊوز تائين سڀني پهچن کي تالا ذريعي ڪنٽرول ڪيو ويندو.
ساڳي ڊيٽا تي شيئر ٿيل لاڪ ٻيهر قابل استعمال آهن- ڪيترائي عمل انهن کي وٺي سگهن ٿا. اهي تالا ٻين عملن کي ڊيٽا تبديل ڪرڻ کان روڪيندا آهن، يعني. اهي مسلسل ڊيٽابيس اسٽيٽ جي ونڊوز ٺاهڻ لاء استعمال ڪيا ويا آهن.
خاص تالا ڊيٽا تبديلين لاء استعمال ٿيندا آهن - صرف هڪ عمل اهڙي تالا وٺي سگهي ٿو. هڪ خاص تالا کڻي سگهجي ٿو:
- ڪو به عمل جيڪڏهن ڊيٽا مفت آهي
- صرف اهو عمل جنهن ۾ هن ڊيٽا تي هڪ گڏيل تالا آهي ۽ هڪ خاص تالا جي درخواست ڪرڻ لاء پهريون هو.

ويزيبلٽي ونڊو جيتري تنگ هوندي، اوترو ئي وڌيڪ ٻين عملن کي ان لاءِ انتظار ڪرڻو پوندو، پر ان جي اندر ڊيٽابيس جي حالت جيتري وڌيڪ مطابقت رکي ٿي.
READ_COMMITTED - هن سطح جو خلاصو اهو آهي ته اسان ٻين موضوعن مان صرف ڪم ٿيل ڊيٽا ڏسون ٿا. جيڪڏهن ٻئي ٽرانزيڪشن ۾ ڊيٽا اڃا تائين انجام نه ڏني وئي آهي، پوء اسان ان جي پراڻي ورزن کي ڏسو.
هي اسان کي اجازت ڏئي ٿو ته ڪم کي متوازي ڪرڻ جي بدران بند ٿيڻ جي انتظار ۾.
خاص چالن جي بغير، اسان IRIS ۾ ڊيٽا جي پراڻي ورزن کي ڏسڻ جي قابل نه هوندا، تنهنڪري اسان کي لاڪ سان ڪرڻو پوندو.
ان جي مطابق، اسان کي حصيداري لاڪ استعمال ڪرڻو پوندو ته ڊيٽا کي صرف مطابقت جي لمحن تي پڙهڻ جي اجازت ڏيڻ لاء.
اچو ته چئو ته اسان وٽ صارف جو بنياد ^ شخص آهي جيڪو هڪ ٻئي ڏانهن پئسا منتقل ڪري ٿو.
شخص 123 کان شخص 242 تائين منتقلي جو لمحو:
LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)ڊيبٽ ڪرڻ کان پهريان شخص 123 کان رقم جي رقم جي درخواست ڪرڻ جو لمحو هڪ خاص بلاڪ سان گڏ هوندو (ڊفالٽ طور):
LOCK +^person(123)
Write ^person(123)۽ جيڪڏهن توهان کي پنهنجي ذاتي اڪائونٽ ۾ اڪائونٽ اسٽيٽس ڏيکارڻ جي ضرورت آهي، ته پوء توهان استعمال ڪري سگهو ٿا هڪ گڏيل تالا استعمال ڪريو يا ان کي استعمال نه ڪريو:
LOCK +^person(123)#”S”
Write ^person(123)بهرحال، جيڪڏهن اسان فرض ڪريون ٿا ته ڊيٽابيس جا عمل لڳ ڀڳ فوري طور تي ڪيا ويندا آهن (مون کي توهان کي ياد ڏيارڻ ڏيو ته گلوبلز هڪ تعلقي جدول جي ڀيٽ ۾ تمام گهٽ سطح جي جوڙجڪ آهن)، پوء هن سطح جي ضرورت گهٽجي ٿي.
بار بار پڙهڻ - هي اڪيلائي جي سطح ڊيٽا جي ڪيترن ئي پڙهڻ جي اجازت ڏئي ٿي جيڪا سمورو ٽرانزيڪشن ذريعي تبديل ٿي سگهي ٿي.
ان جي مطابق، اسان کي تبديل ڪرڻ واري ڊيٽا کي پڙهڻ لاءِ هڪ شيئر لاڪ لڳائڻو پوندو ۽ ان ڊيٽا تي خاص لاڪ لڳائڻو پوندو جيڪو اسان تبديل ڪندا آهيون.
خوشقسمتيءَ سان، LOCK آپريٽر توهان کي تفصيل سان لسٽ ڪرڻ جي اجازت ڏئي ٿو تمام ضروري تالا، جن مان تمام گهڻو ٿي سگهي ٿو، هڪ بيان ۾.
LOCK +^person(123, amount)#”S”
чтение ^person(123, amount)ٻيا عمل (هن وقت متوازي سلسلا تبديل ڪرڻ جي ڪوشش ڪندا آهن ^person(123، رقم)، پر نٿا ڪري سگهن)
LOCK +^person(123, amount)
изменение ^person(123, amount)
LOCK -^person(123, amount)
чтение ^person(123, amount)
LOCK -^person(123, amount)#”S”جڏهن لسٽنگ لاڪ ڪاما سان الڳ ڪيا ويا آهن، اهي ترتيب سان کنيا ويندا آهن، پر جيڪڏهن توهان هي ڪريو ٿا:
LOCK +(^person(123),^person(242))ان کان پوء اهي سڀ هڪ ڀيرو ايٽمي طور تي ورتو وڃي ٿو.
SERIALIZE ڪريو - اسان کي لاڪ قائم ڪرڻا پوندا ته جيئن آخرڪار سڀئي ٽرانزيڪشن جن ۾ عام ڊيٽا هجي انهن کي ترتيب سان عمل ۾ آندو وڃي. ھن طريقي لاءِ، گھڻا لاڪ خاص ھئڻ گھرجن ۽ ڪارڪردگيءَ لاءِ عالمي جي ننڍين ننڍين علائقن کي ورتو وڃي.
جيڪڏهن اسان عالمي ^ شخص ۾ فنڊ ڊيبٽ ڪرڻ جي ڳالهه ڪريون ٿا، ته پوءِ ان لاءِ صرف SERIALIZE آئسوليشن ليول قابل قبول آهي، ڇو ته رقم سختي سان ترتيبوار خرچ ٿيڻ گهرجي، ٻي صورت ۾ اهو ممڪن آهي ته ساڳئي رقم ڪيترائي ڀيرا خرچ ڪجي.
4. Durability
مون استعمال ڪندي ڪنٽينر جي سخت ڪٽڻ سان ٽيسٽ ڪيا
docker kill my-irisبنياد انھن کي چڱي طرح برداشت ڪيو. ڪو به مسئلو نه سڃاتو ويو.
ٿڪل
عالمي لاءِ، InterSystems IRIS وٽ ٽرانزيڪشن سپورٽ آهي. اهي واقعي ايٽمي ۽ قابل اعتماد آهن. گلوبلز جي بنياد تي ڊيٽابيس جي تسلسل کي يقيني بڻائڻ لاء، پروگرامر ڪوششون ۽ ٽرانزيڪشن جي استعمال جي ضرورت آهي، ڇاڪاڻ ته ان ۾ پيچيده تعمير ٿيل تعميرات جهڙوڪ پرڏيهي چابيون نه هونديون آهن.
لاڪ استعمال ڪرڻ کان سواءِ گلوبلز جي آئسوليشن ليول READ UNCOMMITED آهي، ۽ جڏهن لاڪ استعمال ڪيو وڃي ته ان کي SERIALIZE سطح تائين يقيني بڻائي سگهجي ٿو.
گلوبلز تي ٽرانزيڪشن جي درستي ۽ رفتار گهڻو ڪري پروگرامر جي مهارت تي منحصر آهي: وڌيڪ وسيع طور تي شيئر ٿيل لاڪ استعمال ڪيا ويندا آهن جڏهن پڙهڻ، اعلي سطحي اڪيلائي، ۽ وڌيڪ تنگ خاص تالا کنيا ويندا آهن، ڪارڪردگي تيز.
جو ذريعو: www.habr.com
