-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于乐观锁 #24
Comments
你说的属于悲观锁解决超卖方案,每次更新前要select for update给指定商品信息加排他锁,然后阻塞其他请求,但这种情况下并发性能大大降低。 |
try {
sg.setVersion(goodsMapper.getVersionByGoodsId(goods.getId()));
ret = goodsMapper.reduceStockByVersion(sg);
}
我比较好奇的是这里,我觉得第一个语句多余,你根据id获取版本号,但是版本号是为了乐观锁,而你在更新时候的时候
@update("update sk_goods_seckill set stock_count = stock_count - 1, version= version + 1 where goods_id = #{goodsId} and stock_count > 0 and version = #{version}")还是直接使用更新语句,我的意思是你更新的时候可以直接更新@update("update sk_goods_seckill set stock_count = stock_count - 1 where goods_id = #{goodsId} and stock_count > 0")不需要select for update,因为不需要查询什么东西是我哪里理解有问题嘛?希望指教!
623585001@qq.com
发件人: 江云雄
发送时间: 2019-05-08 19:30
收件人: zaiyunduan123/springboot-seckill
抄送: Lxiaolong; Author
主题: Re: [zaiyunduan123/springboot-seckill] 关于乐观锁 (#24)
你说的属于悲观锁解决超卖方案,每次更新前要select for update给指定商品信息加排他锁,然后阻塞其他请求,但这种情况下并发性能大大降低。
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
乐观锁发生冲突时版本号已经被其他请求+1,所以重试时需要获取最新的版本号,直接update还是用原来的版本号,会一直重试失败。 |
我的意思是不用版本号,直接
@update("update sk_goods_seckill set stock_count = stock_count - 1 where goods_id = #{goodsId} and stock_count > 0")
623585001@qq.com
发件人: 江云雄
发送时间: 2019-05-09 14:05
收件人: zaiyunduan123/springboot-seckill
抄送: Lxiaolong; Author
主题: Re: [zaiyunduan123/springboot-seckill] 关于乐观锁 (#24)
乐观锁发生冲突时版本号已经被其他请求+1,所以重试时需要获取最新的版本号,直接update还是用原来的版本号,会一直重试失败。
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
直接update还是会导致超卖问题,如果需要用排他锁,update之前要select for update申请排他锁才可以。 |
直接update会默认X锁,我用mysqlslap 并发测试了,不会出现超卖情况
623585001@qq.com
发件人: 江云雄
发送时间: 2019-05-09 14:35
收件人: zaiyunduan123/springboot-seckill
抄送: Lxiaolong; Author
主题: Re: [zaiyunduan123/springboot-seckill] 关于乐观锁 (#24)
直接update还是会导致超卖问题,如果需要用排他锁,update之前要select for update申请排他锁才可以。
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
我又测试出一个让我很不解的结果。直接update和用乐观锁实现都不会出现超卖,但是效率有很大区别
第一条是直接更新,利用mysql的X锁实现不超卖,第二条相当于实现一个乐观锁,但是执行update的时候还是会使用X锁,但是效率更快了,这是什么原因造成的
可以解答一下吗,谢谢
623585001@qq.com
发件人: 623585001@qq.com
发送时间: 2019-05-09 15:32
收件人: zaiyunduan123/springboot-seckill
主题: Re: Re: [zaiyunduan123/springboot-seckill] 关于乐观锁 (#24)
直接update会默认X锁,我用mysqlslap 并发测试了,不会出现超卖情况
623585001@qq.com
发件人: 江云雄
发送时间: 2019-05-09 14:35
收件人: zaiyunduan123/springboot-seckill
抄送: Lxiaolong; Author
主题: Re: [zaiyunduan123/springboot-seckill] 关于乐观锁 (#24)
直接update还是会导致超卖问题,如果需要用排他锁,update之前要select for update申请排他锁才可以。
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
stock_count > 0 这个条件已经是乐观锁了。根本不会出现超卖现象。那个版本号原理就是cas,在这里有点多此一举。同时redis是单线程,根本不会有两个线城同时减库存,所以不可能存在超卖现象 |
确实是这样的,因为加了库存判断,这就已经解决超卖问题,是我理解有误。 |
学习了,谢谢,刚刚我也是在这个环境又疑惑,5次判断乐观锁,如果数量不是 更新减一,而是用户自己下单的数量减N,那这一步是比较好的 |
afterPropertiesSet();这个同步mysql和redis库存的操作,因为mysql和redis的速率不同导致redis上的库存已经用完但是mysql还没来得及更新,然后afterPropertiesSet()会把redis上的库存同步为mysql上一样的,会不会产生大量的redis上的超卖 |
不会,这个同步是初始化的时候同步,redis库存用完意味着此次秒杀结束 |
long stock = redisService.decr(GoodsKey.getGoodsStock, "" + goodsId);//10 |
昂,你应该这样理解,超卖是出现数据库为负数的情况,所以就算redis缓存同步为上次一样的也没关系,这样的后果只是多一些人来参加秒杀,但是不会出现超卖,这些人最后的结果的是秒杀失败。 |
我在想redis上如果不出现超卖,那mybatis上是不是也不会超卖,然后mybatis上是不是就不用加锁了 |
mysql更新操作默认加X锁,数据库主要控制好事务,下单,减库存要加事务。还有我估计这里同步还是考虑到秒杀取消订单的情况。redis单线程,你直接实现不超卖也可以。 |
谢谢大佬代码学习了 |
hello,你是如何测试的,然后确认的乐观锁性能要比悲观锁性能高, 并发多少 , |
这个如果只有乐观锁去判断的话,那不是秒杀的时候失败的概率会很高? |
本人小白,mysql的update本身具有排他锁,@update("update sk_goods_seckill set stock_count = stock_count - 1, version= version + 1 where goods_id = #{goodsId} and stock_count > 0 and version = #{version}"),更新库存应该不存在安全问题,为什么还需要根据版本来实现乐观锁,希望释疑。
The text was updated successfully, but these errors were encountered: