這可能是一個不同的壞主意,或者我們必須解決的一個數據庫併發問題。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