2010-07-21 34 views
1

我的應用程序的一部分有一個競爭條件,其中多個線程可能最終創建相同的持久對象。所以,我已經實現的代碼看起來像這樣:用Django ORM + MySQL/InnoDB捕捉競爭條件的正確方法

from foobar.models import Bar 

def testomatic(request): 
    bar = None 
    tries = 0 
    while not bar: 
     try: 
      bar = Bar.objects.get(b=2) 

     except Bar.DoesNotExist: 
      time.sleep(10) # put in here to force the race condition 
      bar = Bar(a = 2, b = 2) 
      try: 
       bar.save() 
      except IntegrityError: 
       tries += 1 
       bar = None 

      if tries > 1: 
       raise Exception("something bad happened") 

    return HttpResponse("tries = %s" % tries) 

而且這部作品在我的測試環境好 - 但是當我跑這跟「真實」的類,它似乎旋轉,多次得到什麼從一開始( ),但始終在save()上收到IntegrityError。

我使用MySQL/InnoDB作爲數據庫引擎。是否有關於MVCC處理的某些事情阻止我獲得記錄,但是當我嘗試創建它時給我一個重複的鍵錯誤?

+0

看起來像這是http://stackoverflow.com/questions/2235318/how-do-i-deal-with-this-race-condition-in-django的副本,答案就在那裏 – 2010-07-22 19:10:29

回答

0

執行此操作的正確方法是刪除原始SQL,以便在執行初始SELECT時鎖定表,然後創建並保存該對象(如果該對象不存在),然後解鎖該表。