高并发下,如何修改余额?

这篇博客探讨了在并发请求下用户余额扣除可能导致的问题,如双重扣款。介绍了使用事务和CAS(Compare And Set)策略来解决并发更新余额的冲突。事务通过`FOR UPDATE`锁定行确保数据一致性,而CAS则在更新时基于初始值进行比较更新,防止并发导致的错误。然而,简单的CAS更新可能存在不幂等性,可能导致重复扣款。实际业务中需要考虑更多细节以确保扣款操作的正确性。
摘要由CSDN通过智能技术生成

  

高并发下,如何修改余额?

  假设一个用户数据 :

  id?12 | user_name?放放 | fee? 30 | updated_at ? 2021-09-06 15:51:33

  修改余额

  //消费金额

  $spend=10;

  //查询用户余额

  $user=select id,fee from `users` where id=12;

  //计算金额

  $newFee=$user['fee']-$spend;

  //.. 这里检查余额是否足够

  //更新余额

  update `users` set fee=$newFee where id=12 ;

  按照正常逻辑来说上面更新余额是没问题的

  但是如果发生并发 当 A 跟 B 同时发起请求时

  请求A 查询出余额为 30

  请求B 查询出余额为 30

  请求B 更新余额为20

  请求A 更新余额为20

  最终用户余额为 20

  也就是说 用户余额为30 两个请求都消费了 10元 即 30 - 10 -10=10 但是当发生并发请求时 余额最终为20 这里的金额是错误的

  在请求B 修改了 余额之后 请求A的查询出来的余额已经不是正确的了 导致了 余额更新错误

  当请求A 执行时 先加入锁 阻塞 请求B直到 请求A完成之后 请求B 才继续执行

  当然使用事务 并不是那么明智

  //开始事务

  begin;

  //消费金额

  $spend=10;

  //查询用户余额

  $user=select id,fee from `users` where id=12 for update;

  //计算金额

  $newFee=$user['fee']-$spend;

  //.. 这里检查余额是否足够

  //更新余额

  update `users` set fee=$newFee where id=12 ;

  //确认成功之后 提交事务

  commit

  什么是 CAS

  在更新的时候使用初始值(即查询出来的当前余额)作为条件 compare 限制只有当初始值没有改变时才允许更新成功 set

  Compare And Set(CAS)

  使用该方式 修改 更新语句

  //消金额

  $spend=10;

  //查询用户余额

  $user=select id,fee from `users` where id=12;

  $oldFee=$user['fee'];

  //计算金额

  $newFee=$user['fee']-$spend;

  //.. 这里检查余额是否足够

  //更新余额

  update `users` set fee=$newFee where id=12 and fee=$oldFee ;

  这里如果发生同时修改产生并发 将只有一边修改成功 这时候如果产生失败 可以对他进行重试等操作

  例如 :

  update users set fee=fee - $spend where id=12 ;

  这里要再加上余额的判断避免出现担保负数金额

  update users set fee=fee - $spend where id=12 and fee >=$spend ;

  稍微改一下这里的更新 语句 也能完成正确的更新 就算是并发也都将正常

  但是这样做将产生一个问题 不幂等

  什么是不幂等 ?

  在相同的条件下 , 执行同一请求,得到的结果相同才符合幂等性

  也即是说

  fee=fee - $spend 不幂等

  fee=$newFee 幂等

  不幂等的情况下 如果发生重复执行的情况将产生重复扣款

  事实上实际业务如何正确的扣款 根据业务的实际情况 可能需要注意更多细节 , 越大的业务量,需要面对更多的问题处理更多的细节. 以上的方案也仅仅是最基础的处理 实际情况需要更多的耐心和思考 共勉之 ~

  

高并发下,如何修改余额?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT是一款跨平台的C++图形用户界面应用程序开发框架,支持高并发解析数据的例子主要有以下几种场景: 1. 网络通信:在网络通信过程中,需要不断地接收和解析数据。例如,一个实时的聊天应用程序,当有大量用户同时发送消息时,服务器需要高并发地接收和解析这些消息,并进行相应的处理和转发。 2. 数据库操作:在数据库操作过程中,可能会涉及到大量的查询和更新操作。例如,一个在线商城的电子支付系统,当有多个用户同时访问时,需要高并发地查询用户的账户余额,并进行相应的扣款或充值操作。 3. 多线程处理:QT提供了多线程编程的支持,可以将一个任务拆分成多个子任务,并利用多个线程并发地处理。例如,一个图片处理程序,当需要同时处理多张图片时,可以将每张图片的处理放在一个独立的线程中进行,从而实现高并发的图片处理。 4. 并行计算:QT中的QtConcurrent框架可以帮助我们实现并行计算。例如,一个大数据处理程序,当需要对大量数据进行计算时,可以将计算任务拆分成多个子任务,利用多线程并发地进行计算,从而提高计算速度和效率。 综上所述,QT提供了丰富的工具和功能来支持高并发解析数据的场景,无论是网络通信、数据库操作、多线程处理还是并行计算,都可以通过QT的相关组件和框架来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值