全栈开发
数据库
【Q234】以下 SQL 语句会有什么问题 (悲观锁)

以下 SQL 语句会有什么问题 (悲观锁)

更多描述 一个计数器,自增一

begin;
select count from user;
 
-- 根据以上 SQL 查询出来的 count 来进行自增
-- 如果在此次事务中,已有多次事务对 count 进行了多次更改怎么办?
update user set count = $count + 1 where id = 1;
commit;

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 235 (opens in a new tab)

Author 回答者: shfshanyue (opens in a new tab)

在并发情况下会出现问题,先查看本次事务的流程

  1. 查询当前计数 -> 此时为 10
  2. 对当前计数自增 -> 此时为 11?在自增时,有可能被多并发的其它事务已经自增到 100 了,此时若设置为 11,肯定有问题

如何解决?

要在第一步时加锁,同一时间只放行一个事务,可以设置分布式锁和悲观锁

  • 分布式锁 (redis):SET LOCK_KEY RANDOM_VALUE EX 100 NX
  • 悲观锁select count from user for update