并发情况下切忌通过java代码更新mysql资金字段。
“王二,username=00010001这个账户多了10万块钱,赶紧排查一下原因。”
“开玩笑吧”
对于用户出金,mysql数据库一般有两张表,money_transfer和usermoney表,然后逻辑上有以下步骤:
- 用户提出出金申请,usermoney表中可用资金减去出金金额,冻结资金增加出金金额。
- money_transfer表中增加一条出金记录,状态为待审核。
- 管理员拒绝了出金申请。
- 4.
如果通过java代码来实现,则如下:
MoneyUser moneyUser = moneyUserMapper.selectByPrimaryKey(members.getUid());
// 可用资金+入金金额
moneyUser.setTotaaymoney(moneyUser.getTotalpayey().add(moneyTransfer.getount()));
this.moneyUserMapper.updateByPrimaryKey(moneyUser);
这样的代码在出现并发的时候,获取moneyUser对象的时候,其中的冻结资金和可用资金加入都是0,那么两个并发在update的时候,两个都执行了,但是起初的冻结资金和可用资金相同,就会导致有一笔资金没有加上。
调试的时候更容易发现这个问题。OH,my 噶,真是个大问题,还出在资金的问题时,我真庆幸这个问题发生的频率不够高。不过我到底是应该庆幸还是不庆幸呢,也许次数发生的多起来的时候,我就更容易来反思来找出问题的症结所在。
那么问题怎么解决呢?
UPDATE moneser
SET
frozapital = frozpital - #{amount,jdbcType=DECIMAL},
totaloney = totaloney + #{amount,jdbcType=DECIMAL}
WHERE uid = #{uid,jdbcType=INTEGER}
通过在sql语句中进行字段的更新操作,而不是在Java类中,因为mysql本身是会有这方面的处理方式的。
这个问题,之前领导有建议我在update数据的时候尽量在sql语句中加入,而不是类字段中做处理。
笑对现实的无奈,不能后退的时候,不再傍徨的时候,永远向前 路一直都在──陈奕迅《路一直都在》
本文出自:【沉默王二的博客】