zoukankan      html  css  js  c++  java
  • 一种登记账后余额的处理方法

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

    第一种方案,使用乐观锁
    实现过程:
    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

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

  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/hifong/p/8401397.html
Copyright © 2011-2022 走看看