这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
分类
高并发情况下,一般采用乐观锁的方式来保证账户余额的正确性。账户的竞争对象及处理方式见下表:
分类 | 处理方式 |
---|---|
用户与用户 | 快速失败,提醒稍后再试 |
系统与系统 | 多次尝试,保存可重试信息 |
系统与用户 | 多次尝试,保存现场 |
设计
账户表
public class Account {
@Id
private Long id;
@Column(nullable = false)
private Bigdecimal Money;
// 乐观锁控制
@Version
private int version;
}
记录表
public class AccountRecord {
@Id
private Long id;
private Long accountId;
@Column(nullable = false)
private Bigdecimal payMoney;
@Column(nullable = false)
private Bigdecimal incomeMoney;
}
注意:记录表中是否要增加余额字段,要根据情况来定,如果记录表不允许用户删除和修改,建议加上,方便核账及排查,反之不要加。
用户与用户竞争--多端操作
当用户在多个终端同时进行提现时前端校验是失效的,就有可能发生锁竞争,但这种情况属于用户的主动操作,所以我们可以在发生乐观锁时直接返回错误信息,警告用户勿频繁操作,流程图如下:
系统与系统竞争
充值成功后,三方返回异步通知,系统进行账户操作,此时也刚好系统在发放红包,就有可能发生锁竞争,因为都是系统内的操作,所以我们一定要保护好现场,并在发生乐观锁异常时,一方要有重试机制,重试达到设定值后,要保存所必须的信息,以便后续人工干预并重新执行任务。流程图如下:
最后
总结一下,系统内部的,切记要有重试机制并可再次执行,用户类的主动操作就不用考虑那么多,直接返回错误信息就好。