余额流水表

版本一

事务过程:

  • 更新 t_acct.balance
  • 创建 t_acct_data 流水
drop table IF EXISTS t_acct;
create table t_acct(
 acct_id int primary key NOT NULL COMMENT '账户id',
 balance decimal(12,2) NOT NULL COMMENT '账户余额',
 -- 乐观锁解决事务并发问题,【高并发】场景下会出现大量事务失败
 version INT NOT NULL DEFAULT 0 COMMENT '版本号,每次更新+1'
)COMMENT '账户表';

drop table IF EXISTS t_acct_data;
create table t_acct_data(
 id int AUTO_INCREMENT PRIMARY KEY COMMENT '编号',
 acct_id int primary key NOT NULL COMMENT '账户id',
 price DECIMAL(12,2) NOT NULL COMMENT '交易额',
 open_balance decimal(12,2) NOT NULL COMMENT '期初余额',
 end_balance decimal(12,2) NOT NULL COMMENT '期末余额'
) COMMENT '账户流⽔表';

问题:并发场景下t_acct_data出现重复数据,跳过了先成功的事务结果

版本二

Tip

借鉴 mysql 事务处理的思路,日志先行,异步处理

事务过程:

  • 创建 t_acct_log 日志
  • 更新 t_acct.balance

异步处理:根据t_acct_log的数据来⽣成t_acct_data记录

drop table IF EXISTS t_acct;
create table t_acct(
 acct_id int primary key NOT NULL COMMENT '账户id',
 balance decimal(12,2) NOT NULL COMMENT '账户余额',
 -- 新增⼀个字段`oldbalance
 old_balance decimal(12,2) NOT NULL COMMENT '账户余额(⽼的值)',
 version INT NOT NULL DEFAULT 0 COMMENT '版本号,每次更新+1'
)COMMENT '账户表';

drop table IF EXISTS t_acct_data;
create table t_acct_data(
 id int AUTO_INCREMENT PRIMARY KEY COMMENT '编号',
 acct_id int primary key NOT NULL COMMENT '账户id',
 price DECIMAL(12,2) NOT NULL COMMENT '交易额',
 open_balance decimal(12,2) NOT NULL COMMENT '期初余额',
 end_balance decimal(12,2) NOT NULL COMMENT '期末余额'
) COMMENT '账户流⽔表';

--  新增⼀个账户操作⽇志表解决【高并发】问题
drop table IF EXISTS t_acct_log;
create table t_acct_log(
 id INT AUTO_INCREMENT PRIMARY KEY COMMENT '编号',
 acct_id int primary key NOT NULL COMMENT '账户id',
 price DECIMAL(12,2) NOT NULL COMMENT '交易额',
 status SMALLINT NOT NULL DEFAULT 0 COMMENT '状态,0:待处理,1:处理成功'
) COMMENT '账户操作⽇志表';