以下 SQL 语句会有什么问题 (悲观锁)
更多描述 一个计数器,自增一
begin;
select count from user;
-- 根据以上 SQL 查询出来的 count 来进行自增
-- 如果在此次事务中,已有多次事务对 count 进行了多次更改怎么办?
update user set count = $count + 1 where id = 1;
commit;
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 235
Author 回答者: shfshanyue
在并发情况下会出现问题,先查看本次事务的流程
- 查询当前计数 -> 此时为 10
- 对当前计数自增 -> 此时为 11?在自增时,有可能被多并发的其它事务已经自增到 100 了,此时若设置为 11,肯定有问题
如何解决?
要在第一步时加锁,同一时间只放行一个事务,可以设置分布式锁和悲观锁
- 分布式锁 (redis):
SET LOCK_KEY RANDOM_VALUE EX 100 NX
- 悲观锁:
select count from user for update