美文网首页技术分享
针对账户扣款如何处理并发问题

针对账户扣款如何处理并发问题

作者: 星可码农 | 来源:发表于2019-11-05 09:44 被阅读0次

首先针对扣款操作第一步从数据库查询账户余额
select * from user_account where uid =#{uid}
然后进行扣款操作,当余额充足时直接扣除
UPDATE user_account SET money=new_money WHERE uid=uid;
想象一下,当同一个用户只有这一个操作账户表时是没有问题的,但是当多处操作增删改查时就会出现数据乱掉,并
发的问题;
每次这时把账户表锁住,进行悲观锁操作,是可以达到效果,但是影响使用的效果
同一个用户,并发扣款时,有小概率会出现异常,可以对每一个用户进行分布式锁互斥,例如:在redis/zk里抢到一个key才能继续操作,否则禁止操作。

这种悲观锁方案确实可行,但要引入额外的组件(redis/zk),并且会降低吞吐量。
极限情况下,可能出现这样的异常流程:步骤一,业务1和业务2并发查询余额,是100元。

步骤一,业务1和业务2并发查询余额,是100元。

image

画外音:这些并发查询,是在不同的站点实例/服务实例上完成的,进程内互斥锁肯定解决不了。

步骤二,业务1和业务2并发进行逻辑计算,算出各自业务的余额,假设业务1算出的余额是28元,业务2算出的余额是38元。

image

步骤三,业务1对数据库中的余额先进行修改,设置成28元。业务2对数据库中的余额后进行修改,设置成38元。

image

此时异常出现了,原有金额100元,业务1扣除了72元,业务2扣除了62元,最后剩余38元。 画外音:假设业务1先写回余额,业务2再写回余额。

对于小概率的不一致,有没有乐观锁的方案呢?

对并发扣款进行进一步的分析发现:
(1)业务1写回时,旧余额100,这是一个初始状态;新余额28,这是一个结束状态。理论上只有在旧余额为100时,新余额才应该写回成功。

而业务1并发写回时,旧余额确实是100,理应写回成功。

(2)业务2写回时,旧余额100,这是一个初始状态;新余额28,这是一个结束状态。理论上只有在旧余额为100时,新余额才应该写回成功。

可实际上,这个时候数据库中的金额已经变为28了,所以业务2的并发写回,不应该成功。

如何低成本实施乐观锁?
在set写回的时候,加上初始状态的条件compare,只有初始状态不变时,才允许set写回成功,Compare And Set(CAS),是一种常见的降低读写锁冲突,保证数据一致性的方法。

此时业务要怎么改?
使用CAS解决高并发时数据一致性问题,只需要在进行set操作时,compare初始值,如果初始值变换,不允许set成功。

具体到这个case,只需要将:
UPDATE t_yue SET money=new_money WHERE uid=uid;
升级为:
UPDATE t_yue SET money=new_money WHERE uid=uid AND money=$old_money;
即可。

并发操作发生时:
业务1执行:
UPDATE t_yue SET money=28 WHERE uid=$uid AND money=100;

业务2执行:
UPDATE t_yue SET money=38 WHERE uid=$uid AND money=100;
这两个操作同时进行时,只可能有一个执行成功。

相关文章

  • 针对账户扣款如何处理并发问题

    首先针对扣款操作第一步从数据库查询账户余额select * from user_account where uid...

  • 热点账户高并发记账方案

    热点账户高并发记账方案 热点账户高并发记账带来的问题? 记账处理过程主要包括两部分,一是记录记账凭证,二是更新账户...

  • [账户]授权扣款账户

    1、账户描述 {根据《付款确认书》,万科股份授权托管人于各笔入池应收账款债权到期日,从万科股份授权扣款账户中直...

  • java并发问题如何处理

    java并发问题如何处理 如何解决并发带来的脏数据问题? 1、使用synchronized来起到同步加锁的作用,首...

  • Controller控制并发锁解决方案

    问题描述 针对Controller接收消息处理,过程中非常多涉及数据并发访问,造成代码重复执行的问题,比如微信支付...

  • Java中Volatile和synchronized

    JMM 内存模型:Java Memory Model问题:并发过程中如何处理可见性 原子性和有序性问题 并发编程中...

  • Shopify 收款方式之Paypal

    在Shopify中,商家经常会面临一个问题: 如何利用Paypal来收款? 如何设置Paypal账户来收款? 针对...

  • face 29高并发大流量

    高并发大流量 并发 并发访问,在某个时间点 有多少个访问同时到来 php如何处理网站大流量高并发问题 流量优化 防...

  • JMM之重排序&Happens-Before

    并发编程中,需要处理两个关键问题: 线程之间如何通信?—共享内存+消息传递 线程之间如何同步? java的并发采用...

  • 慧定投跟踪观察记录(2017-02-10)

    今日账户情况(2017-02-10) 往期扣款情况 最近一次扣款(2017.02.07) 解释:目前,沪深300指...

网友评论

    本文标题:针对账户扣款如何处理并发问题

    本文链接:https://www.haomeiwen.com/subject/safsbctx.html