5.5 用户下单与秒杀
流程:100件商品 -----> 下单 ------> 付款
我们的项目是在下单的时候进行的扣减库存,实际项目有的是在付款的时候进行扣减库存
下单的时候扣减库存:会存在少卖的问题(因为有的人下单了,未付款,导致100件商品只卖出去80件),但不存在超卖的问题(也就是不可能100件商品,卖了120件)
我们项目只解决了下单时的并发承载问题,没有再深入解决付款的问题
1. 本项目表设计亮点
-
order_info订单表:订单以后会非常的庞大,所以要将历史订单卸载出去,所以表设计时,将id设置成年月日开头+商品流水号,为了方便将来做表的拆分
-
serial_number表:用于设计订单流水号的号码的步长,value是商品流水的最大值,step是步长1,每次操作商品流水号的时候,都要for update一下,加上一个行锁(有索引的话,for update就是行锁,没有索引for update就是行锁)
2. 下单操作(超卖问题、面试高频)
下单的时候去扣减库存(锁库存),这种在下单的时候扣减库存的方法解决了超卖的问题,订单以后会非常的庞大,所以要将历史订单卸载出去,所以表设计时,将id设置成年月日开头+商品流水号,为了方便将来做表的拆分
3. 数据库事务(InnoDB)具体见那个思维导图
MVCC既保证了事务、又保证了并发性
脏读:对某一事务,读取另外一个事务未提交的数据。如下图:
不可重复读:某一个事务,对同一个事务前后读取的数据不一致,比如下图中因为事务1已经将N值修改,并且已经提交,所以事务2前后读的数据不一致:
幻读:对某一事务,对同一个表前后查询到的行数不一致,比如下图,事务一新增了一行数据,并且将其提交,所以事务2中,原来读的是3行数据,现在可以读4行数据。
**第一类丢失更新:**某一事务的回滚,导致另外一个事务已更新的数据丢失;
**第二类丢失更新:**某一事务的提交,导致另外一个事务已更新的数据丢失
隔离级别 | 是否存在脏读 | 是否存在不可重复读 | 是否存在幻读 |
---|---|---|---|
read uncommitted 读未提交 | 存在 | 存在 | 存在 |
read committed 读已提交 | 不存在 | 存在 | 存在 |
repeatable read 可重复读 | 不存在 | 不存在 | 存在 |
serializable 可串行化 | 不存在 | 不存在 | 不存在 |
4. MVCC(它是乐观锁)
对MVCC的理解。在视频1:13分钟左右
当要修改一份数据时,就复制出一份副本出来,在副本上做修改;如果别人要进行读数据,那么读的是之前旧版本的数据
这个对MVCC的通俗解释更好理解:视频1:59:09处 https://www.nowcoder.com/study/live/660/5/5
5. Spring种7种事务的传播机制
所谓的Spring种事务的传播机制就是指的是:多个含事务的方法在互相调用的时候,事务如何在这些方法之间进行传播,Spring给出了7种不同的传播特性,来保证事务的正常执行。
为了方便理解这个题目,现在假定有这么一个场景A类的a方法现在要准备调用B类的b方法,由于7种有的不太常见,下面先展示常用的事务:
- REQUIRED:这个是默认的传播特性。如果a方法没有事务,那么b方法就需要新建一个事务,如果a方法存在事务,那么b方法就加入a的事务;
- REQUIRES_NEW: 不管a方法里面是否有事务,每次都会创建一个新的事务去运行(如果a方法之前有事务,就将其挂起,a方法原来就没有的话,那就更要new一个新的事务去运行了)
- NESTED: 这个中文名其实就是“筑巢”的意思,如果当前方法a事务存在,则b方法就嵌套在事务中执行
- 其他的还有NEVER、NOT_SUPPORT、MANDATORY、SUPPORTS