方案一: 悲观锁
在更新之前,先利用事务和行锁机制,把待更新的数据锁住,其他 session 无法读取和更新这一行.
具体实现:
set auto_commit = false;
begin;
select * from table where id = 1 for update;
update table set num = num + 1 where id = 1;
commit;
set auto_commit = true;
方案二:乐观锁
更新之前不对记录加锁,而是在更新的时候增加条件,保证只有一个请求更新成功;
select * as rs from table where id = 1;
update table set num = num + 1 where id = 1 and num = rs.num;
然后查看更新成功的条数,如果是0条表示没有更新成功;可以采用重试机制
方案三: 将类似的字段放到 Redis 中维护,规避这种问题
Redis 自带的 incr 和 decr 操作具有原子性,可以保证数据一致性