今天这节课我们来说一下电商的账户系统。

账户系统负责记录和管理用户账户的余额,这个余额就是每个用户临时存在电商的钱,来源可能是用户充值或者退货退款等多种途径。

从业务需求角度来分析,一个最小化的账户系统,它的数据模型可以用下面这张表来表示:

image.png

这个表包括用户 ID、账户余额和更新时间三个字段。每次交易的时候,根据用户 ID 去更新这个账户的余额就可以了。

为什么总是对不上账?

每个账户系统都不是孤立存在的,至少要和财务、订单、交易这些系统有着密切的关联。理想情况下,账户系统内的数据应该是自洽的。**所有用户的账户余额加起来,应该等于这个电商公司在银行专用账户的总余额。**账户系统的数据也应该和其他系统的数据能对的上。比如说,每个用户的余额应该能和交易系统中充值记录,以及订单系统中的订单对的上。

不过,由于业务和系统的复杂性,现实情况却是,很少有账户系统能够做到一点不差的对上每一笔账。所以,稍微大型一点儿的系统,都会有一个专门的对账系统,来核对、矫正账户系统和其他系统之间的数据差异。

对不上账的原因非常多,比如业务变化、人为修改了数据、系统之间数据交换失败等等。那作为系统的设计者,我们只关注“如何避免由于技术原因导致的对不上账”就可以了,有哪些是因为技术原因导致的呢?比如说:网络请求错误,服务器宕机、系统 Bug 等。

“对不上账”是通俗的说法,它的本质问题是,冗余数据的一致性问题

通过冗余数据,我们完全可以通过用户的每一笔充值、消费数据,来计算用户当前的账单余额是多少

同时流水也是十分重要的,不然如果由于系统bug导致的余额错误是无法修复的。

设计账号流水时,要遵循下面两个原则

  1. 流水只能新增,如果取消交易,可以新增一笔取消交易的流水。
  2. 流水表必须递增,需用用流水号确定顺序。

在对账时,如果发现流水和余额不一致,无法通过业务的办法排查问题,一般以交易流水为准。

使用事务保证数据一致性

比如说新增流水和修改余额,两个操作要么都成功,要么都失败。就需要事务来保证。