高并发下账户余额扣减解决方案

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

分类

高并发情况下,一般采用乐观锁的方式来保证账户余额的正确性。账户的竞争对象及处理方式见下表:

分类 处理方式
用户与用户 快速失败,提醒稍后再试
系统与系统 多次尝试,保存可重试信息
系统与用户 多次尝试,保存现场

设计

账户表

1
2
3
4
5
6
7
8
9
10
11
12
kotlin复制代码public class Account {

@Id
private Long id;

@Column(nullable = false)
private Bigdecimal Money;

// 乐观锁控制
@Version
private int version;
}

记录表

1
2
3
4
5
6
7
8
9
10
11
12
13
kotlin复制代码public class AccountRecord {

@Id
private Long id;

private Long accountId;

@Column(nullable = false)
private Bigdecimal payMoney;

@Column(nullable = false)
private Bigdecimal incomeMoney;
}

注意:记录表中是否要增加余额字段,要根据情况来定,如果记录表不允许用户删除和修改,建议加上,方便核账及排查,反之不要加。

用户与用户竞争–多端操作

当用户在多个终端同时进行提现时前端校验是失效的,就有可能发生锁竞争,但这种情况属于用户的主动操作,所以我们可以在发生乐观锁时直接返回错误信息,警告用户勿频繁操作,流程图如下:

未命名文件.png

系统与系统竞争

充值成功后,三方返回异步通知,系统进行账户操作,此时也刚好系统在发放红包,就有可能发生锁竞争,因为都是系统内的操作,所以我们一定要保护好现场,并在发生乐观锁异常时,一方要有重试机制,重试达到设定值后,要保存所必须的信息,以便后续人工干预并重新执行任务。流程图如下:

未命名文件 (1).png

最后

总结一下,系统内部的,切记要有重试机制并可再次执行,用户类的主动操作就不用考虑那么多,直接返回错误信息就好。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%