మాడ్యూల్ పాఠాలు (2/4)
జాతి పరిస్థితులు
ఒకే టెర్మినల్లో డేటాబేస్ ఐసోలేషన్లో ఎలా పనిచేస్తుందో అర్థం చేసుకోవడం చాలా సులభం, కానీ నిజమైన వెబ్ దృష్టాంతంలో వందలాది ఏకకాల "నోడ్/PHP/Go" ప్రక్రియలు అభ్యర్థనలను పంపుతాయి. ఇక్కడే ప్రసిద్ధ జాతి పరిస్థితులు పుట్టాయి.
"లాస్ట్ అప్డేట్" సమస్య
రెండు థ్రెడ్లు ఒకే పాత వరుసను చదివి, JavaScript సర్వర్లో దానిపై కొంత గణితాన్ని చేసి, ఆపై ఫలితాన్ని సేవ్ చేయడానికి UPDATEని తిరిగి పంపినప్పుడు లాస్ట్ అప్డేట్ జరుగుతుంది.
దృష్టాంతం:
- ఉత్పత్తి #5 10 యూనిట్లను కలిగి ఉంది.
- వినియోగదారు A ఒకదాన్ని కొనుగోలు చేస్తుంది (సర్వర్ A "10" అని చదువుతుంది, "9"ని గణిస్తుంది).
- A యొక్క కొనుగోలు COMMIT దశను పూర్తి చేయడానికి ముందు అదే మిల్లీసెకండ్ వినియోగదారు B మరొకదాన్ని కొనుగోలు చేస్తారు.
- సర్వర్ B కూడా "10" చదువుతుంది, "9"ని గణిస్తుంది.
- సర్వర్ A
UPDATE: set quantity = 9ని పంపుతుంది. - సర్వర్ B
UPDATE: set quantity = 9ని పంపుతుంది. - ఇద్దరూ తమ సంఖ్యను విజయవంతంగా తగ్గించారని అనుకుంటారు. కానీ తుది విలువ 8 యూనిట్లు ఉండాలి! ఫాంటమ్ కొనుగోలు కోల్పోయింది.
భారీ లావాదేవీలు లేకుండా పరిష్కారం (అటామిక్ అప్డేట్లు)
గణితాన్ని బయట చదవడం మరియు చేయడం కాకుండా, ఎల్లప్పుడూ సమకాలీకరించబడే నవీకరణ సమయంలోనే DBని చేయనివ్వండి.
-- Wrong
UPDATE products SET stock = 9 WHERE id = 5;
-- Correct and natively thread-safe
UPDATE products SET stock = stock - 1 WHERE id = 5;మరిన్ని తీవ్రమైన క్రమరాహిత్యాలు (డర్టీ రీడ్లు & ఫాంటమ్స్)
- డర్టీ రీడ్: కమిట్ ద్వారా ఇంకా ధృవీకరించబడని వేరొకరి తాత్కాలిక డేటాను మీరు చదివారు (మరియు అకస్మాత్తుగా మిమ్మల్ని చెల్లుబాటు చేయకుండా ROLLBACKకి వెళ్లవచ్చు).
- ఫాంటమ్ రీడ్లు: మీరు అన్ని అడ్డు వరుసలను స్కాన్ చేస్తారు, అదే సమయంలో రెండవ థ్రెడ్ కొత్త రికార్డ్ను ఇన్సర్ట్ చేస్తుంది, ఆపై అదే లావాదేవీ సమయంలో మీరు మరొక స్కాన్ చేయండి మరియు లెక్కించిన ఆర్థిక నివేదికలను రాజీ చేస్తూ కొత్త రికార్డ్ ఎక్కడా కనిపించకుండా అద్భుతంగా కనిపిస్తుంది.
చిన్న స్ట్రింగ్ మానిప్యులేషన్ కోసం కస్టమర్ల రికార్డ్ను అటామిక్గా సవరించండి.\nఒక నక్షత్రం గుర్తును జోడించడానికి మేము కస్టమర్ యొక్క 'నగరం' పేరు మార్చాలనుకుంటున్నాము. \n id=10 ఉన్న దాని కోసం అడ్డు వరుస యొక్క స్వంత విలువను పెంచడం ద్వారా దీన్ని చేయండి, ప్రస్తుత విలువకు ' - పాత'ని కలపండి (పోస్ట్గ్రెస్' || సంగ్రహణ పైపును ఉపయోగించండి).
సూచనను చూపించు
కస్టమర్లను అప్డేట్ చేయండి SET city = నగరం || ' - పాతది' ఎక్కడ id = 10;
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
చెల్లింపులు మరియు ధరలలో క్లాసిక్ కోల్పోయిన అప్డేట్ జరుగుతుంది.\nఅత్యవసర ధరల పెంపు ఉందని అనుకుందాం: 'order_items' టేబుల్ (ఆర్డర్ 1 యొక్క ఉత్పత్తి 1 కోసం) 'unit_price'ని పరమాణుపరంగా 20% పెంచండి, అంటే JS ప్రీకంప్యూట్ చేసిన కొత్త ధరను మాన్యువల్గా చొప్పించడానికి బదులుగా * 1.2ని గుణించడం.
సూచనను చూపించు
ఆర్డర్_ఐటెమ్లను అప్డేట్ చేయండి SET unit_price = unit_price * 1.2 WHERE order_id = 1 మరియు product_id = 1;
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది