我正在运行一堆异步工作线程,并希望通过以下方式创建一个事务:
更新
我想确保:
两个 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()
之间的短时间内,数据库中的某些内容可能会发生变化。