最近遇到一些简单并发问题的记录
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最近遇到一些简单并发问题的记录相关的知识,希望对你有一定的参考价值。
1. 程序代码加锁,可以用JAVA.concurrent.包下的Lock类,比如营销系统的记账流水,详细可参见这块的代码...........
2. 清结算系统接口定时任务批量通知X变现更新用户的变现资产,同一个人多比变现会更新出现脏数据,采用行级索就能解决
<!-- 成功变现后更新用户的成功变现金额和成功变现后的剩余资产 --> <update id="updateSuccedAssetsByFpOrderId" parameterType="com.***.***.p2p.domain.loan.BxdLoan" > update bxd_mem_assert set succed_bx_money = succed_bx_money + #{bxMoney,jdbcType=DECIMAL}, succed_surplus_assets = succed_surplus_assets - #{bxMoney,jdbcType=DECIMAL} - #{bxInterests,jdbcType=DECIMAL}, update_time = now() where fp_order_id = #{fpOrderId,jdbcType=VARCHAR} </update>
<!-- 取消变现、流标/取消放款后的资金回退,恢复用户的变现前的变现金额和剩余资产 --> <update id="updateRollbackAssetsByFpOrderId" parameterType="com.***.***.p2p.domain.loan.BxdLoan" > update bxd_mem_assert set bx_money = bx_money - #{bxMoney,jdbcType=DECIMAL}, surplus_assets = surplus_assets + #{bxMoney,jdbcType=DECIMAL} + #{bxInterests,jdbcType=DECIMAL}, update_time = now() where fp_order_id = #{fpOrderId,jdbcType=VARCHAR} and bx_money > 0 </update>
3.借款人在点取消变现的同时,用户在产品详情页点了下单按钮,主要是前端页面停顿到提交到后台业务逻辑处理的时差问题导致的。需要双向控制:
1)在更新变现单状态为‘已取消’时,需要先检测是否存在订单,采用update status where exists select order
2)在用户下单的后台逻辑里,要先检查是否用户已经取消了变现,即此产品是否还处于在售中的状态,虽然用户一开始看到的是在售中,通过此状态链接进入了购买页面,但是下单之前可能已经被改掉了。
<!-- 取消变现: 更新产品状态为:已取消,程序后续还要更新变现单状态为“取消变现” 通过行级索方式控制 可取消条件:在售中的变现单、且此变现单不存在有效地投资的订单(除状态为3交易取消,8交易关闭之外的订单都认为为有效订单) --> <update id="updateForCancelByProductId" parameterType="java.lang.String" > UPDATE bxd_prd_base prd SET prd.status_code = ‘12‘, prd.status_value = ‘已取消‘ WHERE EXISTS ( SELECT bl.loan_id FROM bxd_loan bl WHERE bl.del_flag = 0 AND bl.loan_id = #{productId,jdbcType=VARCHAR} AND bl.status_code = 1 AND bl.loan_id = prd.product_id AND NOT EXISTS (SELECT bod.product_id FROM bxd_ord_detail bod WHERE bl.loan_id = bod.product_id AND bod.status_code NOT IN (3, 8)) ) </update>
4. XXX宝申购,或者前台表单提交没有防重,或者由于网络的问题,导致一个请求到后台变成了2此接口请请求 ,导入用户一个x变现订单同时申购了两次。
解决办法:
1) 前端:加上防重机制:如var submitLock=false;,并且如果是$.ajax的话,设置成同步,不要异步!
2) 后端:控制器通过Token控制
3) 数据库层每次insert前都要确保没有相同的流水插入过,通过在流水号字段加唯一索引,保证同一个业务只插一条记录,并且根据insert的返回值进行下一步操作!或者直接通过下面的语句:
INSERT INTO `bxd_tnb_trade_wait` (`account_no`, `order_id`, `trade_money`, `status_code`, `record_count`, `add_time`, `update_time`, `del_flag`)
SELECT ‘6976870‘,‘601000284‘,‘9999999‘,‘9‘,‘9‘,‘20169-09-19 19:59:09‘,‘2019-09-19 19:59:09‘,‘0‘ FROM DUAL
WHERE NOT EXISTS (SELECT order_id FROM bxd_tnb_trade_wait WHERE order_id=‘601000233‘)
以上是关于最近遇到一些简单并发问题的记录的主要内容,如果未能解决你的问题,请参考以下文章