余额流水表
版本一
事务过程:
- 更新 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 '账户操作⽇志表';