抢单功能,电商超卖功能等场景需要考虑并发问题。
解决方案:
第一种设置数据库事务的隔离级别,设置喂Serializable,效率低下
第二种使用乐观锁解决,通过版本号进行控制
原理:我们在数据表上面添加一个乐观锁字段,数据类型是整数的,用来记录数据更新的版本号,这个跟SVN机制很像。
乐观锁是一种逻辑锁,他是通过版本号来判定有没有更新冲突出现。
比如说,现在A商品的乐观锁版本号是0,现在有事务1来抢购商品了。事务1记录下版本号是0,等到执行修改库存的时候,就把乐观锁的版本号设置成1。但是事务1在执行的过程中,还没来得及执行UPDATE语句修改库存。这个时候事务2进来了,他执行的很快,直接把库存修改成99,然后把版本号变成了1。这时候,事务1开始执行UPDATE语句,但是发现乐观锁的版本号变成了1,这说明,肯定有人抢在事务1之前,更改了库存,所以事务1就不能更新,否则就会出现超售现象。
简单说就是基础sql语句:
update order_info set status=2,uid=? where id=?
变成
update order_info set status=2,uid=? where id=? and status=1
where语句后面相当于加了一个乐观锁,后面的线程执行时更新记录为0,那么我就可以返回抢单失败。
spring框架中,乐观锁一般搭配@Transactional注解(事务)使用。
第三种加锁解决,synchronized及lock锁、分布式锁。
synchronized及lock锁都是本地锁,只在当前jvm生效。对集群环境不生效
synchronized测

最低0.47元/天 解锁文章
1474

被折叠的 条评论
为什么被折叠?



