2016-03-03 47 views
0

我跑了一堆異步的工人,並希望通過建立一個交易:Django的交易通過列值

UPDATE

我要確保:

兩個aysnc工人不會覆蓋同騎

兩個異步工人不相同的分配車騎

def my_func(ride_id): 
    ride = Ride.objects.get(id=ride_id) 
    if not ride.driver_id: 
     with transaction.atomic(): 
      driver_id = find_best_driver_not_assigned() # this could return same driver in two different workers 
      # This code executes inside a transaction. 
      ride.driver_id = 1 
      ride.save() 

driver_id列最初保持空白。但是任何「贏得」或更新字段的人都應該阻止來自其他異步芹菜工作者的任何其他寫入。

問題是,這ride條目的route字段正在更新每秒,我只想要一個例外,如果有人試圖更新driver_id字段。

這項工作?

回答

2

不,這不起作用,因爲您已將driver_id支票置於交易之外。

is_new_driver = Ride.objects.filter(id=ride_id, driver_id=None).update(driver_id=1) 

這將原子設置driver_id如果不是:

幸運的是,你根本不爲這個需要交易,因爲你可以完成一個在Django/SQL原子獲取和設置已經設置好了,您可以使用返回值來確定是否是這種情況。見documentation for update(),其中指出:

使用update()也防止競爭條件,其中一些可能會在數據庫中的時間加載對象並調用save()之間短期內改變。

+0

這太棒了!謝謝 – DaynaJuliana

+0

我應該注意哪些例外?一個如果過濾器失敗,另一個如果更新失敗? – DaynaJuliana

+0

@DaynaJuliana:樂於助人。沒有任何異常可以捕獲 - 根據'driver_id'是否已經存在,返回值將簡單地爲'0'或'1'。 (好吧,DatabaseErrors對任何查詢都是可能的,但在這方面沒有什麼特別的關於'filter()'和'update()')。 –