目标
我想根据搜索条件更新单个记录(类似于findOne,但我想更新One(。不过,这必须是原子性的,因为.find() then .update()
将利用节点的极好的异步特性,并在查找后和更新前保留记录以供更改。
示例
为了简化事情,我有我想通过网站借给朋友的财产记录。如果两个朋友同时想借任何一本书,我需要将其属性标记为正在使用,以防止出现问题。
如果我先使用Book.find(available==true)
,然后使用Book.update(book, available=false)
,这可能会有一个竞争条件,线程运行.find()
,在等待DB的回复时,为另一个用户调用.find()
,这两个条件都会导致借出同一本书。这显然是一个问题,也是我想要避免的。
问题
如何防范这种情况?有没有一种方法可以使用水线的辅助方法来更新一条记录?还是我需要执行本机SQL查询?
您可以使用mongodb原生findAndModify((:
var ObjectId = require('mongodb').ObjectID;
Book
.native(function (err, collection) {
collection.findAndModify(
{_id: new ObjectId(Id), available: true},
{$set:{ available: false}},
{ upsert: true }
function (err, result) {
// manage after update
}
});