- 做的项目中,有一个功能是用户投资,需要每次更改所投资项目的剩余完成金额,而且最终投资不能超过投资目标金额.但是当多线程同时操作访问修改数据库的时候,可能会造成超出的状况.为了避免这种情况发生,我使用了mysql的乐观锁机制.
所以我给表中数据增加了一个version字段来控制数据的更改操作记录,原理就是每次用户要更改数据时,mysql执行语句时就会多一个判断,判断用户当前提交的version和当前要修改的数据中的version是否相同,如果不同则更改数据库数据失败.
当然这是简单的防止超卖例子,真正解决高并发的问题,还是要用到其他技术,如消息队列等.
LoanInfo loanInfo = loanInfoMapper.selectLoanInfoByLoanId(loanId);// 根据产品标识获取产品详情
int version = loanInfo.getVersion();// 获取当前产品记录的版本号
paramMap.put("uid", sessionUser.getId());//用户标识
paramMap.put("phone", sessionUser.getPhone());//用户手机号
paramMap.put("loanId", loanId);//产品标识
paramMap.put("bidMoney", bidMoney);//投资金额
paramMap.put("version", version);
int updateLoanInfoCount = loanInfoMapper.updateLoanInfoById(paramMap);
<update id="updateLoanInfoById">
<![CDATA[
update
b_loan_info
set
left_product_money = left_product_money-#{bidMoney},
version = version+1
where
id = #{loanId} and version = #{version} and (left_product_money - #{bidMoney}) >= 0
]]>
</update>
- 如上,用户每次点击投资,都会调用查询当前投资信息的方法,得到当前version,然后修改数据库,数据库会进行判断version版本字段信息是否相同.因为每次修改数据库成功,version会加1,所以如果出现多线程同时进行修改的时候,就只有一个会成功.