这可能是一个不同的坏主意,或者我们必须解决的一个数据库并发问题。MongoDB数据库信号量和Node.js Process.NextTick()
我们有一个被调用来更新mongo记录的方法。我们看到一些并发问题 - 进程A读取记录,进程B读取记录,进程A制作mods并保存记录,进程制作B mods并保存记录。因为B在A之后读取,所以在A写入之前,它不知道A所做的更改,并且我们丢失了来自A的数据。我想知道我们是否不能使用数据库信号量,集合,这是一个布尔值。如果我们在方法开始时读取记录,并且该字段为真,则正在编辑它。此时,使用process.nexttick()重新调用该方法,并使用相同的数据。否则,设置信号量,并继续。
读取和保存之间仍然会有一段时间,但它应该比我们现在要做的更快。
是这样的。任何想法,任何人都做过这样的事情?它会工作吗?
function remove_source(service_id,session, next)
{
var User = Mongoose.model("User");
/* get the user, based on the session user id */
User.findById(session.me,function(err,user_info)
{
if (user_info.semaphore === true)
{
process.nextTick(remove_source(service_id,session,next));
}
else
{
user_info.semaphore = true;
user_info.save(function(err,user_new)
{
if (err) next(err,user_new);
else continue_on(null,user_new);
});
}
function continue_on(user_new)
{
etc.......
}
编辑:新代码:
功能现在看起来如下。我正在对阵列进行单独更新。这当然意味着如果第一次和第二次事务之间的事务失败,我现在有可能使数据不同步。我在想,我可以简单地重新保存在进入函数时检索到的用户对象,覆盖我的更改。我不知道,如果我没有改变这个对象,Mongoose/Mongo是不会做这个保存的,我们不得不去试试看。还有什么想法?
var User = Mongoose.model("User");
/* get the user, based on the session user id */
User.findById(session.me,function(err,user_info)
{
if (err)
{
next(err,user_info,null);
return;
}
if (!user_info || user_info.length === 0)
{
next(_e("ACCOUNT_NOT_FOUND"),"user_id: " + session.me);
return;
}
var source_service_info = _.where(user_info.credentials, {"source_service_id": service_id});
var source_service = source_service_info.source_service;
User.findByIdAndUpdate(session.me,{$pull: {"credentials": {"source_service_id": service_id}}},{},function(err,user_credential_removed)
{
if (err)
{
next(err,user_info,null);
return;
}
User.findByIdAndUpdate(session.me,{$pull: {"criteria": {"source_service": source_service}}},{},function(err,user_criteria_removed)
{
if (err)
{
next(err,user_info,null);
return;
}
else
{
next(null,user_criteria_removed);
}
});
});
});
};
您可能只是想为您的文档添加版本,并根据读取后版本未更改的版本进行有条件更新。如果它未能更新,您会知道自上次读取以来进行了修改。 – WiredPrairie