为了账号安全,请及时绑定邮箱和手机立即绑定

支付系统 遇到了一个读取账户余额加锁的问题 该如何解决

支付系统 遇到了一个读取账户余额加锁的问题 该如何解决

蝴蝶刀刀 2018-11-17 17:22:42
第一次做支付系统,我们平台有很多商户,每个商户每分钟订单很多,量很大,我用异步方式给商户账户更新余额,用的mysql队列,每笔订单成功都会往队列里加如一条,crontab来读取更新增加账户余额,但是碰到了一个提现的问题提现我是这么做的,账户余额减去提现金额,然后再把剩余的钱更新到账户余额字段,问题就有了!1.提现的时候拿到账户余额为10块,要提现5块,提现操作正在进行,但是这个时候进来一笔5块的订单,异步要更新账户,拿到的还是10块,加上5块,然后把15元更新到余额字段中,这时候提现操作也在进行,提现了5块,然后在把剩余的5块更新到余额字段, 覆盖了之前的15,2.我没有在提现查询余额的时候加锁,加锁能否解决问题呢,除了加锁,是否还有其他更好的方法解决呢。这个异步更新账户余额的逻辑和提现的逻辑是否需要改进呢。希望大家能能大家给点意见谢谢第一条是入账的,第一个字段是ID 第二个余额,第三个订单金额,第四个更新完后的余额,第二条是提现的,第二个余额,第三个是提现的金额,第四个同上
查看完整描述

1 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

增加余额

set autocommit=0;update <table> set balance=balance+<xxx> where id=<id>;select * from <table> where id=<id>commit;

保证上面2条语句在同一个事务中执行。最终在程序中做运算。

  • balance - <xxx> 就是增加前的余额

  • balance 就是增加后的余额

提现

set autocommit=0;update <table> set balance=balance-<xxx> where id=<id> and balance>=<xxx>;select * from <table> where id=<id>;commit;

保证上面2条语句在同一个事务中执行。最终在程序中做运算。

  • balance + <xxx> 就是提现前的余额

  • balance 就是提现后的余额


查看完整回答
反对 回复 2018-11-17
  • 1 回答
  • 0 关注
  • 959 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信