看起來像您的問題聲明的是,
如果其他進程已更新了記錄,則因爲傳遞(在內存中)的版本比在數據庫中的一個已經存在的(最近由以前的進程更新)下的代碼不應該更新它。
然而,如果傳遞的版本等於已經存在的最大的版本,那麼它應該更新的一個。
,如果傳入的版本是嚴格更大,那麼它應該插入記錄。
您可以使用下面的代碼來實現它,但是這不是在生產環境中爲它不是一個語句中發生的事情,因此原子不能保證一個非常優雅的解決方案。可能不會像prod環境那樣非常優雅,但是您可以根據您的要求在其上構建它。
--in the variable userToUpdate, change the version to 0, 1 and 2 to see different types of behaviors as explained in the above 3 points.
db.t1.drop(); //drop if exist
db.t1.save({uname:"sachin", v:0, email:"email-0"});
db.t1.save({uname:"sachin", v:1, email:"email-1"});
//----
var userToUpdate = {uname:"sachin", v:2, email:"email-2"};
//----
var user = userToUpdate.uname;
var cur = db.t1.find({uname:user}).sort({v:-1}).limit(1);
var latestVersion = 0;
if(cur.hasNext()){
var v1 = cur.next();
latestVersion = v1['v'];
printjson('latestVersion='+latestVersion);
}
versionToUpdate = (userToUpdate.v < latestVersion)? -1 : userToUpdate.v;
if(versionToUpdate != -1){
printjson('Going to upsert');
db.t1.update({uname:user, v:versionToUpdate}, userToUpdate, {upsert:true});
}else{
printjson('latest version in db : '+latestVersion+', which is greater than the passed version '+userToUpdate.v+', hence ingoring');
}
[**'$ setOnInsert' **](http://docs.mongodb.org/manual/reference/operator/update/setOnInsert/)應該允許您這樣做。 – chridam