Skip to content

Instantly share code, notes, and snippets.

@pfmiles
Created May 22, 2012 09:46
Show Gist options
  • Save pfmiles/2767916 to your computer and use it in GitHub Desktop.
Save pfmiles/2767916 to your computer and use it in GitHub Desktop.
超级麻烦的、基于“乐观锁”的mongoDB原子更新操作(在老值上加上一个新值)
// 1.查找相同主键对象
DBObject old = col.findOne(qo);
if (old == null) {
// 2.若不存在,尝试插入, 若出错"duplicate 主键",则转到3.更新操作
try {
col.insert(newObj, WriteConcern.SAFE);
} catch (DuplicateKey e) {
// 2.1 瞬间又被插了一条记录,尝试更新操作
BasicDBObject upObj = new BasicDBObject();
WriteResult rst = null;
int countDown = MAX_TRY_COUNT;
do {
old = col.findOne(qo);
upObj.putAll(unit.merge(old.toMap()));
rst = col.update(old, upObj);
countDown--;
} while (!(Boolean) rst.getField("updatedExisting") && countDown > 0);
if (countDown <= 0) log.error("Update failed after " + MAX_TRY_COUNT + " times retry, tableName: "
+ tableName + ", _id: " + _id);
}
} else {
// 3.新老两条记录的合并、更新操作,且要对照老对象做update操作,若老对象已被更改,则要重新查出老对象、再循环尝试这一步操作
BasicDBObject upObj = new BasicDBObject();
upObj.putAll(unit.merge(old.toMap()));
WriteResult rst = col.update(old, upObj);
int countDown = MAX_TRY_COUNT;
while (!(Boolean) rst.getField("updatedExisting") && countDown > 0) {
old = col.findOne(qo);
upObj.putAll(unit.merge(old.toMap()));
rst = col.update(old, upObj);
countDown--;
}
if (countDown <= 0) log.error("Update failed after " + MAX_TRY_COUNT + " times retry, tableName: "
+ tableName + ", _id: " + _id);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment