System တစ်ခုကို User အများအပြားက တစ်ချိန်တည်း (Exact same time) မှာ အသုံးပြုတဲ့အခါ Data တွေ မှားယွင်းသွားတတ်တဲ့ "Race Condition" ဆိုတဲ့ ပြဿနာကို ကြုံရလေ့ရှိပါတယ်
ဥပမာ အနေ နဲ့ E-commerce မှာ တစ်ခု တည်း ကျန်တယ့် ပစ္စည်း တစ်ခုကို User နှစ်ယောက် က ပြိုင်တူ ဝယ် တယ့် အခါ မျိုး Online ကနေ ticket များကို user အများအပြားက တစ်ပြိုင်တည်း ဝယ်တယ့် အခါမျိုး ဒီလို အခြေအနေ များမှာ Race Condition ဖြစ်သွားပြီး ပြသာနာ ကြုံရတတ်ပါတယ်
ဒီလိုပြသာနာ တွေ ကို ဖြေရှင်းလို့ ရတယ့် နည်းလမ်းတွေက တော့ တစ်ခုထက်မက ရှိပါတယ် ဘယ် နည်းလမ်းကို သုံးပြီးဖြေရှင်း မလဲ ဆိုတာကတော့ ကိုယ့်ရဲ့ project ပေါ်မှာ ပဲ မူတည်ပါတယ်
Database Level မှာတာ့ Pessimistic Locking, Optimistic Locking များကို သုံးပြီး Race Condition ကို ဖြေရှင်းလို့ရပါတယ်
Pessimistic Locking ဆိုတာက Data ကို ဖတ်ပြီး ပြင်ဆင်နေချိန် (Transaction အလုပ်လုပ်နေချိန်) မှာ အခြားဘယ်သူမှ ဝင်ပြင်လို့မရအောင် Lock ချထားတဲ့ စနစ်ပါ။ (ဥပမာ - SQL မှာ SELECT ... FOR UPDATE သုံးတာမျိုး)။ Data accuracy အရမ်းအရေးကြီးတဲ့ နေရာတွေမှာ သုံးလို့ကောင်းပေမယ့် User အများကြီး ဝင်သုံးတဲ့အခါ Performance ကိုတော့ သိသိသာသာ ကျဆင်းစေနိုင်ပါတယ်။
Optimistic Locking ဆိုတာက
Lock အသေမချထားဘဲ Table ရဲ့ Record တစ်ခုချင်းစီမှာ Version number (သို့) Timestamp လေးတွေ ထည့်ထားတဲ့နည်းပါ ကိုယ် Update လုပ်မယ့်အချိန်ရောက်မှ Database ထဲက Version နဲ့ ကိုယ်ယူလာတဲ့ Version ကိုက်/မကိုက် စစ်ဆေးပါတယ် Version မကိုက်တော့ဘူး (တခြားတစ်ယောက်က အရင်ဝင်ပြင်သွားတယ်) ဆိုရင် Exception ပစ်ချပြီး Retry ခိုင်းပါတယ်
System က Server တစ်လုံးတည်း မဟုတ်ဘဲ Microservices တွေ၊ Web Servers အများကြီးနဲ့ Run နေတဲ့ အခြေအနေမျိုးမှာဆိုရင် Database ကိုချည်းပဲ အားကိုးလို့ အဆင်မပြေနိုင်ပါဘူး
Redis ရဲ့ INCR, DECR ဒါမှမဟုတ် Code ထဲမှာဆိုရင် StringIncrementAsync လိုမျိုး Atomic Command တွေကို သုံးပြီး ဖြေရှင်းတာက ပိုပြီးထိရောက်ပါတယ် Redis က Single-threaded Architecture ဖြစ်တဲ့အတွက် Request တွေကို တစ်ပြိုင်တည်း လာနေရင်တောင် တစ်ခုပြီးမှ တစ်ခု (Sequential) အလုပ်လုပ်ပေးသွားပါတယ်
ဒါကြောင့် Counter တွေ၊ တစ်ခုတည်းကျန်တဲ့ Ticket အရေအတွက် လျှော့တာတွေ၊ Unique ဖြစ်တဲ့ Barcode သို့မဟုတ် ID တွေ ထုတ်ပေးတဲ့ နေရာတွေမှာ Race condition မဖြစ်အောင် အကောင်းဆုံး တားဆီးပေးနိုင်ပါတယ်
Application Level Locking ကိုသုံးပြီး လည်း Race Condition ကို ဖြေရှင်းလို့ရပါတယ်
Code ရေးတဲ့အခါ Thread တွေ အများကြီး ပြိုင်မလုပ်နိုင်အောင် ကန့်သတ်တဲ့ နည်းလမ်းပါ
C# လို Language မှာဆိုရင် lock keyword, Mutex, ဒါမှမဟုတ် Asynchronous programming အတွက်ဆိုရင် SemaphoreSlim စတာတွေကို သုံးပြီး အရေးကြီးတဲ့ Code block (Critical Section) ကို တစ်ချိန်မှာ Thread တစ်ခုတည်းကပဲ ဝင်ရောက်ခွင့်ပြုအောင် ထိန်းချုပ်တာပါ
ဒီနည်းလမ်းက Server တစ်လုံးတည်း (Single Instance) မှာပဲ အလုပ်လုပ်ပြီး Server အများကြီးနဲ့ Run တဲ့အခါမှာတော့ အဆင်မပြေပါဘူး
User တွေဆီက လာတဲ့ Request တွေကို တိုက်ရိုက် Process မလုပ်ဘဲ RabbitMQ သို့မဟုတ် Kafka စတဲ့ Message Broker (Queue) တွေထဲကို အရင်ထည့်ပြီး နောက်က Background Worker ကနေ Queue ထဲကနေ တစ်ခုချင်းစီ အစဉ်လိုက် ဆွဲယူပြီး Database ကို အလုပ်လုပ်ခိုင်းတဲ့နည်းလမ်းကို သုံးပြီးလည်း ဖြေရှင်းလို့ရပါတယ်
Top comments (0)