“update t set v = v + 1 where id = 1” 这个语句可以用于数据库某字段值的递增,但在并发情况下,它很容易造成”丢失修改“。要解决这个问题,一般要用乐观锁。 下面是我最近在项目中使用的做法:
--使用cas风格 update t set v = #newValue# where id = 1 and v = #currentValue#
//乐观锁+重试机制,如果重试了一定次数还未成功,则抛出 IllegalStateException
public void increaseValue(long id) throws IllegalStateException {
//如果cas失败,则继续执行,直到100遍
for (int i = 0; i < 100; i++) {
int currentValue = getValueById(id, topicName);
if (currentValue == -1) { //-1代表记录不存在
return;
}
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", id);
params.put("currentValue", currentValue);
params.put("newValue", currentValue + 1);
int updatedRowCount = exec(sql, , params);
if (updatedRowCount > 0) {
return;
}
}
throw new IllegalStateException("failed due to cas retrying error");
}
然后你可以参照这里的代码来做并发测试