將NodeJS與MongoDB + Mongoose結合使用。處理NodeJS異步行爲
首先,我知道異步非阻塞代碼的優點。所以我處理回調。但最後我遇到了以下問題。
可以說我有一個功能可以隨時由用戶調用。有可能,一個超級「閃電般」的用戶幾乎在同一時間調用它兩次。
function do_something_with_user(user_id){
User.findOne({_id:user_id}).exec(function(err,user){ // FIND QUERY
// Do a lot of different stuff with user
// I just cannot update user with a single query
// I might need here to execute any other MongoDB queries
// So this code is a set of queries-callbacks
user.save() // SAVE QUERY
})
}
當然它執行是這樣的:查找查詢,查找查詢,保存查詢,保存查詢
這完全破壞的應用程序的邏輯(應該找到QUERY,SAVE QUERY,查找查詢,保存查詢)。所以我決定通過爲特定用戶「鎖定」整個函數來防止異步行爲(因此函數代碼內部仍然是異步的)。
var lock_function_for_user = {}
function do_something_with_user(user_id){
if(!lock_function_for_user[user_id]){
lock_function_for_user[user_id] = true
User.findOne({_id:user_id}).exec(function(err,user){
// Same code as above
user.save(function(){
lock_function_for_user[user_id] = false
})
})
} else {
setTimeout(function(){
do_something_with_user(user_id)
},100) // assuming that average function execution time is 100ms in average
}
}
所以,我的問題是:這是一個很好的做法,好的破解或壞的破解?如果這是一個不好的破解,請提供任何其他解決方案。特別是,我懷疑這個解決方案在我們擴展和啓動多個NodeJS流程時會起作用。
做你的答案確實有道理。你提到了良好的做法。但是,假設我有FIND-SOMECODE-FIND-SOMECODE-SAVE-SAVE(找到一個文檔,執行某些操作,找到另一個文檔,執行某些操作,同時保存兩個文檔)。看來我不能在這裏使用findAndModify。我想我也不能使用索引。如果Mongo在第二次保存時拋出一個錯誤,我當然可以先回滾一下,但那又怎麼樣?如何嘗試再次調用該函數?所以,即使索引,問題仍然存在。 – igorpavlov
檢查這個網頁:http://docs.mongodb.org/manual/tutorial/isolate-sequence-of-operations/。執行兩階段提交。 –
最後,我需要在這裏。謝謝。我將使用Redis-MongoDB混合。無論如何,你的回答非常有幫助,因爲Redis也是非阻塞的。因此,我將使用多個Redis和Mongo隔離。 – igorpavlov