账户余额更新问题总结

一.账户余额在高并发更新的时候,扣减会出现负数问题?

思路,在sql语句的条件中,设置更新金额减去账户余额一定大于0,对于余额的更新,不使用乐观锁,也没有用查询到的余额作为可以更新的条件,而是设置更新金额减去账户余额一定大于0 ,这是能够高并发更新的关键,因为只有账户的余额不被扣成负数即可

另外,防止高并发余额账户查询的余额已经被其他线程更新,使用行级锁,所以对于查询语句添加for update

例子:

//查询账户的语句
<select id="getAccountInfoByCustomerNo" resultMap="AccountInfoEntityMap">
		SELECT ID,ACCOUNT_TYPE,ACCOUNT_STATUS,MERCHANT_NO,ACCT_NO,BALANCE
		FROM TBL_ACCOUNT_INFO
		where 1=1 AND MERCHANT_NO = #{customerNo} and ACCOUNT_TYPE =#{accountType} AND ACCOUNT_STATUS = 'ACTIVATION' FOR UPDATE
	</select>
<!--更新入款余额-->
	<update id="updateInBalance">
		UPDATE TBL_ACCOUNT_INFO
		<set>
			BALANCE = BALANCE + #{amount,jdbcType=DECIMAL},
			UPDATE_TIME =CURRENT TIMESTAMP
		</set>
		WHERE ACCT_NO = #{acctNo,jdbcType=VARCHAR}
	</update>
<!--更新出款余额-->
	<update id="updateOutBalance" >
		UPDATE TBL_ACCOUNT_INFO
		<set>
			BALANCE = BALANCE - #{amount,jdbcType=DECIMAL},
			UPDATE_TIME =CURRENT TIMESTAMP
		</set>
		WHERE ACCT_NO = #{acctNo,jdbcType=VARCHAR} AND  BALANCE - #{amount,jdbcType=DECIMAL} >= 0

	</update>

重点注意,查询和更新的操作请在一个事物中控制。

二、由于高并发导致本次的查询的账户余额更新之后,添加账户历史的时候如何一一对应?

解决思路,在更新完余额后,重新再次查询余额,然后记录账户历史。来保证数据的准确性。

关于账户历史表的设计中,我们只有进账的方式,本次交易金额,和剩余账户余额,而不记录操作前余额,也是基于高平发的思路。

以下是我们账务历史表的设计:

TBL_ACCOUNT_HISTORY 账户历史表

字段

类型

备注

IDint类型 从0开始自增唯一主键

RELATED_TRANS_ID

VARCHAR(32)
交易订单ID

ACCOUNT_ID

VARCHAR(32)
账户id

DIRECTION

VARCHAR(32)
资金方向(IN,OUT)

AMOUNT

DECIMAL(18,2)当期交易金额

BALANCE

DECIMAL(18,2)当期账户余额

TRX_TYPE

VARCHAR(32)
交易类型(充值,转账,代付,提现)

CREATE_DATE

DATE

创建时间

MERCHANT_NO

VARCHAR(32)
商户编号

REASON

VARCHAR(32)
原因

TBL_ACCOUNT_INFO 账户信息表

字段

类型

备注

IDint类型 从0开始自增唯一主键

ACCOUNT_TYPE

VARCHAR(32)
账户类型

ACCOUNT_STATUS

VARCHAR(32)
账户状态

BALANCE

DECIMAL(18,2)

账户金额

CLOSE_TIME

TIMESTAMP

关闭时间

 

CREATE_TIME

TIMESTAMP创建时间

UPDATE_TIME

TIMESTAMP更新时间

MERCHANT_NO

VARCHAR(32)
商户编号

ACCOUNT_NO

VARCHAR(32)
账户编号

CURRENCY_ENUM

VARCHAR(32)
币种

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值