2010-05-26 64 views
2

我有django應用程序,通過fastcgi在lighttpd下運行。 FCGI運行腳本如下所示:Django多進程問題

python manage.py runfcgi socket=<path>/main.socket 
    method=prefork \                          
    pidfile=<path>/server.pid \                                   
    minspare=5 maxspare=10 maxchildren=10 maxrequests=500 \ 

我使用SQLite。所以我有10個進程,它們都使用同一個數據庫。接下來我有兩個觀點:

def view1(request) 
    ... 
    obj = MyModel.objects.get_or_create(id=1) 
    obj.param1 = <some value> 
    obj.save() 

def view2(request) 
    ... 
    obj = MyModel.objects.get_or_create(id=1) 
    obj.param2 = <some value> 
    obj.save() 

,如果這個觀點在兩個不同的線程執行,有時我得到爲MyModel例如在DB與ID = 1和更新或者參數1或參數2(但不能同時) - 這取決於其過程是第一個。 (當然在現實生活中ID變化,但有時2個進程使用相同的ID執行這兩個視圖)

問題是:我應該怎麼做更新param1和param2的實例?我需要一些東西來合併不同進程中的更改。

一個決定是創建進程間鎖定的對象,但在這種情況下,我會得到順序執行的意見,他們將不能夠同時執行,所以我要求幫助

DUPE的Django: How can I protect against concurrent modification of data base entries

+2

SQLite通常被認爲不適合作爲測試環境之外的後端;遷移到PostgreSQL或MySQL將成爲阻力最小的路徑。 – 2010-05-26 18:21:40

+1

[Django:如何防止數據庫條目的併發修改]的可能重複(http://stackoverflow.com/questions/320096/django-how-can-i-protect-against-concurrent-modification-of-數據庫條目) – 2010-05-26 18:23:46

+0

嗯...可能是這個討論可以是有用的。我可以在我的模型中添加時間戳字段並在保存前更新它。成功更新意味着沒有其他線程/進程沒有改變我的對象,所以我可以調用save方法。但是,如果更新失敗,這意味着其他線程或進程已經改變了它,我應該從數據庫重新獲取並嘗試合併更改。我對嗎? P.S:但是很奇怪,Django對解決這些問題沒有任何幫助......所有的開發人員都可以發明自己的解決方案嗎?這很奇怪 – iKiR 2010-05-27 05:41:18

回答

1

的SQLite如果您需要對數據庫進行併發訪問,這不是一個好的選擇。 我建議切換到一些其他RDBMS,例如MySQL或PostgreSQL, 並且還考慮到get_or_create脆性:

How do I deal with this race condition in django?

關於上述鏈接,也有第二解決這一問題 - 使用READ COMMITED隔離級別,而不是REPEATABLE READ。但是它沒有經過測試(至少在MySQL中),所以可能會有更多的錯誤/問題。

+0

謝謝你的回覆。 嗯......這個問題在MySQL或PostgreSQL中是如何解決的?關於get_or_create - 我讀過這個問題,並且我自己實現了get_or_create(通過繼承管理器),在這個實現中我調用超級實現這個方法,如果它引發了IntegrityError,我接收它,提交事務並再次調用get_or_create。 你能告訴我如何在SQLite中使用READ COMMITED隔離級別? – iKiR 2010-05-27 03:40:14

+0

我不認爲SQLite實現傳統意義上的隔離級別:http://www.sqlite.org/sharedcache.html,但我可能是錯的。不過,如果你想在concurent環境中使用SQLite,那麼更好的做法是爲不可避免的OperationalErrors做準備。 – 2010-05-27 09:08:39