购物车如何设计

购物车存储时需要考虑清楚的问题

  • 1.用户没登录,在浏览器中加购,关闭浏览器再打开,刚才回购的商品还在吗?(存在)
  • 2.用户没登录,在浏览器中回购,然后登录,刚才回购的商品还在不在?(存在)
  • 3.关闭浏览器再打开,上一步回购的商品还在不在?(不存在)
  • 4.再打开手机,用相同的用户登录 ,第二步回购的商品还在不在?(存在)

暂存购物车用户购物车

购物车设计原则

  • 如果未登录,需要临时暂存购物车的商品;
  • 用户登录时,把暂存购物车的商品合并到用户购物车中,并且清除暂存购物车;
  • 用户登陆后,购物车中的商品,需要在浏览器、手机 APP 和微信等等这些终端中都保持同步。

暂存购物车设计

一般的设计都会将这批数据存储在客户端,采用Session、Cookie、LocalStorge,APP的本地存储原理也是类似

  • Session的缺陷:保留时间短
  • Cookie:每次交互都需要把数据给带上,存储上限4K
  • LocalStorage:只能由客户端来访问,

用户购物车设计

使用关系型数据库来存储购物车数据,如果追求性能或者高开发,也可以选择Redis

账户系统的设计

对不上账,最本质的原因就是,冗余数据的一致性问题

账户流水:每一笔交易记录,只能新增

如何保证账户系统中流水和余额的一致

  1. 使用数据库事务来保证数据一致性

    • 原子性
    • 一致性
    • 隔离性
    • 持久性
  2. 事务隔离级别

    • 脏读:每个进行中事务的中间状态,对其他事务都是可见的
    • 不可重复读:在同一个事务内两次读取同一条数据,读到的结果可能会不一样

如何解决跨系统、跨数据库的数据一致性问题?

我们在使用分布式事务时,更多的情况都是使用分布式事务的理论来指导设计和开发。

分布式事务的实现原理

  1. 2PC
    2PC引入了一个事务协调者的角色,来协调多个系统,协调者对客户端提供一个完整的服务,在这个服务内部,协调者再分别调用不同系统间的相应服务
    二阶段指的是准备阶段和提交阶段。
    在准备阶段,协调者对各系统发送【准备】指令,各系统在接收准备命令之后,开始执行准备操作。准备操作包括,除提交数据库事务之外的所有工作。等各个系统都准备完成后,就进入到了提交阶段。
    在提交阶段,协调者再给各系统发送【提交】指令,系统在接收到指令后,都提交自己的数据库事务,然后返回给协调者提交成功的响应。
    协调在接收到所提交成功的响应后,再给客户端返回成功的响应,这样整个分布式事务就完成了。

    以上都不是重点!!!!
    异常了怎么处理才是重点:

    • 在准备阶段:如果任何一步出现错误或者超时,协调者会马上给各系统发送回滚的请求
    • 提交阶段:分布式事务只能成功不能失败!如果是超时那就一直重试,直到提交成功为止。

      2PC适用于对数据一致性要求比较高的场景。要求强一致、并发量不大的情况下

      缺点:整个事务的执行过程需要阻塞服务端的线程和数据库的会话,所以,2PC 在并发场景下的性能不会很高。并且,协调者是一个单点,一旦过程中协调者宕机,就会导致订单库或者促销库的事务会话一直卡在等待提交阶段,直到事务超时自动回滚。

  1. 本地消息表
    本地消息表适合解决分布式最终一致性的问题

    • 实现思路:某一个系统在接收到请求后,正常的使用本地的数据库事务去更新数据库,同时在执行这个事务的过程中,在本地记录一条消息。然后再用一个异步的服务去读取刚刚记录的本地消息,调用自己的服务,这样的话如果是失败了也可以通过重试来解决。最终保证各系统的数据都是一致的。

      本地消息表实现手段:消息队列、数据库、本地磁盘文件

      本地消息表缺点:必须要有一个前提条件,那就是异步执行的那部分操作,不能有依赖的资源。