मैं knex को विस्तार से नहीं जानता और एक त्वरित खोज से, knex वर्तमान में अद्यतन विवरणों पर "सीमा" का उपयोग करने का समर्थन नहीं करता है, इसलिए केवल सामान्य दृष्टिकोण का विवरण है।
पहले मानदंड से मेल खाने वाली पंक्ति के लिए एक अद्यतन करें, फिर उस अद्यतन पंक्ति का चयन करें।
इसलिए, पहले एक अपडेट ऑपरेशन करें जो वर्तमान उपयोगकर्ता आईडी को पहली असंसाधित पंक्ति में असाइन करता है जिसे या तो कोई उपयोगकर्ता असाइन नहीं किया गया है या पहले से ही वही उपयोगकर्ता असाइन किया गया है:
update rows
set assignedTo = user.id
where assignedTo=0 or assignedTo=user.id
order by createdAt asc
limit 1
मुझे लगता है कि यह कच्ची क्वेरी का उपयोग करके knex के साथ इस तरह काम कर सकता है लेकिन कोशिश नहीं की है:
await knex.raw('update rows set assignedTo = :userid where assignedTo=0 or assignedTo= :userid order by createdAt asc limit 1', {userid: user.id})
यह पहली (सबसे पुरानी बनाई गई) पंक्ति की तलाश करेगा जो एक ही उपयोगकर्ता को असाइन नहीं की गई है या पहले से ही असाइन की गई है और फिर उस उपयोगकर्ता को असाइन करें। यह एक बार में होता है।
फिर आप उपयोगकर्ता को निर्दिष्ट पंक्ति की खोज कर सकते हैं:
const notProcessed = await knex('rows')
.select('*'')
.whereRaw(`status='Not-Processed' and assignedTo=${user.id}`)
.orderByRaw('createdAt asc')
.first();
ध्यान दें कि अब हम स्पष्ट रूप से केवल उपयोगकर्ता को पहले से असाइन की गई पंक्ति के लिए कैसे देखते हैं।
संयुक्त
await knex.raw('update rows set assignedTo = :userid where assignedTo=0 or assignedTo= :userid order by createdAt asc limit 1', {userid: user.id})
const notProcessed = await knex('rows')
.select('*'')
.whereRaw(`status='Not-Processed' and assignedTo=${user.id}`)
.orderByRaw('createdAt asc')
.first();
स्पष्ट रूप से आपको चयन की आवश्यकता नहीं है यदि आप तुरंत पंक्ति के साथ काम नहीं करना चाहते हैं।
समस्या यह है कि जब एक ही समय में कई अनुरोधों को संभाला जाता है, तो आपको समानांतर में एक ही समय में चल रहे कोड के कई उदाहरणों की कल्पना करनी होगी। तो, आपके मूल कोड के साथ, उनमें से कोई भी अपडेट करने से पहले दो अनुरोध एक ही समय में आपका चयन कर सकते हैं। तो, उन दोनों की एक ही पंक्ति वापस आ जाएगी।
कथन के भीतर पंक्ति को तुरंत अद्यतन करके, भले ही दो कथन समानांतर में चलते हों, डेटाबेस यह सुनिश्चित करेगा कि वे एक ही पंक्ति को नहीं देखते हैं।
समाधान के लिए एक वैकल्पिक तरीका एक म्यूटेक्स का उपयोग करना होगा (जैसे async-mutex ) अपने मूल कोड के आसपास यह सुनिश्चित करने के लिए कि आपका मूल चयन और अद्यतन ऑपरेशन परमाणु है (एक बार में होता है), लेकिन यह आपके आवेदन के प्रतिक्रिया समय को बढ़ा देगा क्योंकि कुछ स्थितियों में एक अनुरोध हैंडलिंग ऑपरेशन को दूसरे पर इंतजार करना होगा जारी रखने के लिए एक।