Django Transaction By Column Value



我正在运行一堆异步工作线程,并希望通过以下方式创建一个事务:

更新

我想确保:

两个 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字段,我只想要一个例外。

这行得通吗?

不,这行不通,因为您已将driver_id支票放在交易之外。

幸运的是,你根本不需要事务,因为你可以在 Django/SQL 中原子地完成获取和设置:

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

如果尚未设置,这将原子方式设置driver_id,您可以使用返回值来确定是否是这种情况。请参阅update()的文档,其中指出:

使用 update() 还可以防止争用条件,即在加载对象和调用 save() 之间的短时间内,数据库中的某些内容可能会发生变化。

最新更新