2016-03-03 48 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()')。 –