同步操作将从 小柒2012/spring-boot-seckill 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
启动后: Api测试地址 http://localhost:8080/seckill/swagger-ui.html
秒杀商品页地址: http://localhost:8080/seckill
作者说明: https://gitee.com/52itstyle/spring-boot-seckill/wikis/%E7%A7%92%E6%9D%80
SeckillController:
秒杀系统的七种实现:
秒杀一(最low实现):
删除success表,更新该商品为100(方便测试)。用CountDownLatch闭锁和线程池以作压测。查询seckill商品库存,大于0则扣库存并生成订单入库。
for循环中,创建runnable并执行流程,闭锁-1,放入线程池并发执行。闭锁await等待所有完成后,查询完成订单数。
两次:一次100个订单,一次102个订单。超卖现象:是因为在查询库存,扣减库存,生成订单的流程中。当并发查询库存时,
导致两次下单同时查询获取到的就是错误的库存数。
@Transactional:
为什么加了事务注解没有用?
这里加事务只是保证了查询库存和扣减库存 这个流程的原子性(如果查和改 这两个步骤哪个出现问题就回滚,以保证数据的正确性),但并不能保证同时只有一个线程查询库存。
@ServiceLimit:限流注解,限制同一个Ip频繁访问,因此导致超卖问题。
秒杀二(程序锁):
使用ReentrantLock,将查询库存,扣减库存和生成订单的流程加锁,一次只能一个线程访问。但是锁释放 和事务的提交的顺序还是会导致超卖的问题。
@Transactional声明式事务注解,其事务的流程,提交是放在哪里。和finally中的unlock锁释放的顺序,导致下单流程出问题。
应该在事务提交后再进行锁的释放,事务未提交就释放锁,就是事务未提交就有新的线程进来,新的事务读取前一个事务未提交的数据,导致脏读。
将@Transactional的事务级别设置为最高,将所放在controller层也可以。
秒杀三(AOP程序锁): 解决二中锁释放和事务提交顺序导致的问题,@Transactional以AOP注解的方式进行事务的拦截配置。那么锁此时也用AOP注解的方式,且order放在事务后面即可。
秒杀四(数据库悲观锁): 查询库存时for update锁表
秒杀五(数据库悲观锁): 数据库悲观锁 set num = num -1 and num>0 将查询和update放在同一条sql中。抢购多件的话 锁表比较慢。
秒杀六(数据库乐观锁): 加version字段,先查询库存,同时查询出version。更新库存时根据id和version查询,就不会出错了。 UPDATE seckill SET number=number-?,version=version+1 WHERE seckill_id=? AND version = ? 抢的人少时,会出现少买。
秒杀柒(进程内队列) : 用LinkedBlockingQueue,生成订单压入队列,另有一个类从队列消费,取出订单信息并入库。该类实现ApplicationRunner
秒杀八(Disruptor队列):
限流注解会导致少买
秒杀一(超卖) 最简单的查询更新操作,不涉及各种锁,会出现超卖情况。
秒杀二(超卖) 使用ReentrantLock重入锁,由于事物提交和锁释放的先后顺序也会导致超卖。
秒杀三(正常) 基于秒杀二场景的修复,锁上移,事物提交后再释放锁,不会超卖。
秒杀四(少买) 基于数据库悲观锁实现,查询加锁,然后更新,由于使用了 限流 注解(可自行注释),这里会出现少买。
秒杀五(正常) 基于数据库悲观锁实现,更新加锁并判断剩余数量。
秒杀六(正常) 基于数据库乐观锁实现,先查询商品版本号,然后根据版本号更新,判断更新数量。少量用户抢购的时候会出现 少买 的情况。
秒杀七(少买) 基于进程内队列 LinkedBlockingQueue 实现,同步消费,由于使用了 限流 注解(可自行注释),这里会出现少买。如果想正常,去掉startSeckil方法上的@ServiceLimit注解即可。
秒杀八(少买) 基于高性能队列 Disruptor实现,同步消费,由于使用了 限流 注解(可自行注释),这里会出现少买。如果想正常,去掉startSeckil方法上的@ServiceLimit注解即可。
SeckillDistributedController: 分布式秒杀:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。