如何防止并发操作时账户余额的扣费和充值冲突?-灵析社区

Daily毅星

账户余额,充值和扣费, 怎么防止在扣费的时候拿的余额是10块钱,要扣1块钱,然后余额是9块钱 然后同一时间充值拿的余额也是10块钱,充值10块钱。应该是最后充完余额为19元,怎么防止这个并发呢,请问sql应该怎么去写 怎么防止这个并发呢

阅读量:161

点赞量:0

问AI
如果站在必须保证扣费和充值都成功的维度 * 用悲观锁的方式实现 使用用户id做为锁标识,例如 "change:balance:userId:123" 当变更账户余额时(充值或扣费)尝试获得锁,如果获得锁成功则继续变更账户余额,否则阻塞,直到尝试获得锁实施变更账户余额操作,从而保证整个变更余额过程的原子性; * 队列的方式实现 通过队列来实现串行和解耦,将扣费和充值动作都丢到FIFO队列中,在由一个消费者依次去队列中取出要执行的action,这样保证整个更余额过程是同步的(synchronized); «当然这两种方案也可以结合使用» 如果站在高性能的维度 * 可通过乐观锁方式实现 即在获取账户余额时同时获得此时数据的verson, 当变更余额时加上version的判断,例如udpate account_balance set balance = balance + :changeNum, version = version + 1 where user_id = :userId and version = :version «:changeNum为传入的变更余额(扣1块或充值10块), :userId为传入的用户id, :version为传入的数据verison» 此时,sql的响应行数为1则表示更新成,0则表示更新失败(数据已经被其他线程更新)。