掘金 后端 ( ) • 2024-04-09 18:03

theme: scrolls-light

十步杀一人,千里不留行。

1 前言

前文已经介绍了C端账户设计的实践,在本文中将讲述 B 端账户的设计实践,相对于 C 端账户的功能,B 端账户在业务上比较复杂。在本文中将结合业务实践编写代码,帮助大家理解 B 端账户设计的思路和实现过程。B 端的技术实现和 C 端的技术实践是相似的。

2 接口实现

前文已经讲述了 B 端账户的接口设计,关于日志的操作类型和业务类型已经在前文中讲述,这里就直接略过,直接讲述 B 端账户的业务操作。

  • 1 B 端账户的数据分为账户表(账户表不需要分表,但是要分开账户信息和账户余额表)和账户流水表(账户流水表需要根据商户信息按照年份分表)。

  • 2 B 端商户的操作主要分为开户和账户交易,以及冻结和解冻,入账冻结以及解冻出账等操作。账户冻结是为了防止某些入账资金被挪用其它用途而进行的冻结操作,达到专款专用的目的,冻结是为了锁定这一笔资金,在使用时需要根据当时传入的冻结单号进行解冻。入账并冻结是商户收到一笔货款,但是交易状态为冻结状态,暂时不能确认,等待确认交易后才能进行解冻操作,如果用户退款,则需要进行解冻出账操作。一般入账对应着冻结,出账对应着解冻,冻结和解冻可以单独操作,也可以分开执行。

  • 3 账户按照 B 端和 C 端分开,也是为了适应其不同业务特点,账户流水的记录类似于会计的单边账记录方法, C 端和 B 端的分开记录,而不是使用同一条流水。

3 代码实践

对于 B 端的代码也有开户和交易的接口,这里和 C 端的操作类似,只是在判断账户余额时,需要扣除账户的欠款金额和冻结金额进行判断。

3.1 开户和交易

1695049579061.png

3.2 冻结和解冻

账户的冻结与解冻操作比较特殊,需要有一个冻结解冻账户表和冻结解冻流水表。对于每一个 B 端账户而言,冻结的类型会有多种,每一种冻结类型作为账户的一个子账户来使用,类似于专户的概念,对应的冻结解冻流水表就是每个专户的冻结和解冻情况。账户冻结时不会发生账户的动账,只是会增加账户的冻结和解冻金额,具体的冻结金额是在冻结解冻账户表中。

以账户冻结为例,具体的操作如下所示: 1695050486973.png

3.3 入账并冻结和解冻并出账

入账并冻结的操作在账户入账的同时并冻结这部分的资金,具体的操作如下图所示。为了减少事务的执行时间,先将流水在事务外层准备好,分别构建冻结流水和账户流水日志。在事务开始时,需要先对账户添加读锁,然后计算账户的余额和冻结金额,更新账户信息和新增账户流水。随后查询账户的冻结信息如果存在则修改,否则新增冻结类型,并添加入账冻结流水。

1695134005555.png

解冻并出账接口就是将冻结的金额解冻并转出,在解冻时不需要判断账户金额是否足够,因为在冻结金额时已经进行过判断,冻结的存在就是为了避免金额不足的情况。在事务外需要构建操作流水,同时更新账户表,新增账户流水表,解冻冻结账户和解冻流水记录表。

1695134124341.png

4 总结

在本文中,主要讲解了 B 端账户的设计以及实现过程,B 账户的操作涉及内容比较多,尤其是冻结和解冻,还有解冻出账和冻结入账操作,需要了解其基本概念才能更好的掌握账户的代码基本设计思想。本文中所涉及的代码已经上传至 github, 欢迎交流学习。项目地址 springboot-auth