2017-04-28 10 views
5
साथ Django में अगले काम के आइटम प्राप्त

कल्पना कीजिए कि आप काम के आइटम के साथ एक सरल तालिका है:PostgreSQL

|ID |OWNER|... 
+---+-----+--- 
|123|  |... 
|456|  |... 
|789|  |... 

हम अगले काम के आइटम जो एक स्वामी नहीं है, पाने के लिए एक http एपीआई प्रदान करना चाहते हैं अभी तक।

हम PostgreSQL का उपयोग करते हैं।

हम Django-ORM के साथ तालिका तक पहुंचते हैं।

मुझे लगता है कि एपीआई कई उपयोगकर्ताओं द्वारा एक साथ पहुंच प्राप्त होने पर कई दौड़-स्थितियां हैं।

मैं दिए गए टूल्स (पोस्टग्रेएसक्यूएल, डीजेगो) के साथ कैसे सुनिश्चित कर सकता हूं कि सभी दौड़ की स्थिति हल हो जाती है (यदि एक कार्य-वस्तु दो अयस्क उपयोगकर्ताओं को दी जाती है तो यह एक बड़ी गलती है)।

उत्तर

2

Django 1.11, select_for_update के साथ skip_locked का समर्थन करना शुरू किया। इसका मतलब है कि आप save() कॉल पर सहेज सकते हैं क्योंकि आपको इसे किसी मालिक को तुरंत असाइन करने की आवश्यकता नहीं है।

उदाहरण के लिए

, @ user73657 के जवाब के ऊपर का निर्माण:

with transaction.atomic(): 
    work_item = WorkItem.objects.select_for_update().filter(owner__isnull=True).first() 
    work_item.owner = request.user 
    work_item.save(update_fields=['owner']) 

# process work_item 

आप कर सकते हैं:

with transaction.atomic(): 
    work_item = WorkItem.objects.select_for_update(skip_locked=True).filter(owner__isnull=True).first() 
    work_item.owner = request.user 
    # process work_item, edit other fields 
    work_item.save() 

skip_locked=True के साथ, लेन-देन बंद कर दिया पंक्ति को छोड़ देता है, और इसलिए गैर अवरुद्ध है। बोनस के रूप में, आपको केवल पर डीबी पर सहेजने की आवश्यकता होगी।

+1

वाह, 'स्किप लॉकड' अच्छा दिखता है। मुझे यह पोस्ट मिला: https://blog.2ndquadrant.com/what-is-select-skip-locked-for-in-postgresql-9-5/ जो विवरण बताता है। – guettli

1
select_for_update साथ

:

with transaction.atomic(): 
    work_item = WorkItem.objects.select_for_update().filter(owner__isnull=True).first() 
    work_item.owner = request.user 
    work_item.save(update_fields=['owner']) 

# process work_item 

https://docs.djangoproject.com/en/1.11/ref/models/querysets/#select-for-update

select_for_update सुनिश्चित करें कि केवल एक ही कनेक्शन मिलान पंक्तियों तक लेन-देन समाप्त हो गया है अद्यतन कर सकते हैं कर देगा।