Django事务按列值

时间:2016-03-03 01:17:17

标签: django transactions

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

更新

我想确保:

两名aysnc工作人员没有覆盖相同的骑行

两名异步工人没有将汽车分配给同一辆车

function findUser(id, cb) {
    MongoClient.connect(cs, function(err, db) {
        var col = db.collection('users');
        col.findOne({ _id: id }, function(err, user) {
            // Value of user here is always null
            // However, if I manually check the database, 
            // I can clearly see that the user with the 
            // same id does exists.
            return cb(err, user);
        });
    });
}

driver_id列最初保持空白。但无论谁“赢”或更新该领域,都应该阻止其他异步芹菜工人的其他写作。

问题是这个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() 条目的ride字段每秒都在更新,如果有人试图更新route字段,我只想要例外。

这会有用吗?

1 个答案:

答案 0 :(得分:2)

不,这不起作用,因为您已将driver_id支票放在交易之外。

幸运的是,您根本不需要事务,因为您可以在Django / SQL中以原子方式完成get-and-set:

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

如果尚未设置,则会自动设置driver_id,并且您可以使用返回值来确定是否是这种情况。请参阅documentation for update(),其中注明:

  

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