码迷,mamicode.com
首页 > 其他好文 > 详细

一种登记账后余额的处理方法

时间:2018-02-01 23:18:37      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:红色   amount   支付系统   class   and   upd   余额   select   账户   

支付系统的记账业务,需要登记每笔记账流水的账后余额。
在大规模并发条件下,简单使用乐观锁或者悲观锁都回严重的锁定数据库,导致性能变慢,下面介绍优化前和优化后的两种处理思路。

第一种方案,使用乐观锁
实现过程:
Step1:从账户中获取最近余额以及账户当前版本号,代码如下:
Select version, balance from account where customer_no=?
Step2:创建账户流水
Insert into account_flow(version, amount, balance, customer_no) values(:version+1, amount, balance+amount, customer_no)
Step3:更新账户余额
Update account set version=version+1, balance = balance + amount where customer_no=:customer_no and version=:version
在并发量小的时候,这样写基本没有问题,可以保证每笔交易的记账流水都是OK,然而,并发大的时候,会发现Step3中的红色部分的条件,完全Hold不住了,还没等待一笔交易完成,可能version已经变化了不止一次

第二种方案,使用触发器
实现过程:
Step1:创建过程表
Create table account_his(account_id, version, pre_version, balance, pre_balance, uid)
字段分别是:账户ID、当前版本号、前一版本号、当前余额、前一版本余额、唯一ID(后面解释)
Step2:创建针对account的触发器
Create or replace trigger account_change_trigger before update on account for each row
Begin
  insert into account_his values (:old.account_id,:new.version,:old.version,:new.balance, :old.balance,:new.uid)
End
Step3:修改记账过程
1、生成uid=uuid
2、更新账户余额:update account set uid=:uid,balance=balance+amount where account_id=xx
3、登记记账流水:insert into account_flow values(account_id, amount, uid),注,此处暂时不登记余额
4、使用定时器,从account_his中更新account_flow的余额:update account_flow set balance=account_his.balance where account_his.uid=account_flow.uid

虽然触发器对数据库性能存在一定的损失,但这个好处还是明显的。

一种登记账后余额的处理方法

标签:红色   amount   支付系统   class   and   upd   余额   select   账户   

原文地址:https://www.cnblogs.com/hifong/p/8401397.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!