高并发提现问题记录

如果单纯的按照业务逻辑先查询余额再扣除余额进行提现,请求少的时候不会有问题,一旦出现高并发或者用户恶意提现,那么就导致多次提现但是余额只扣了很少。这是由于高并发环境下(操作同一个用户的资金)一个线程进入读取余额100,还没更新完余额100-20,另一个请求就进入读取余额100(应该是80),问题就出现了。所以解决方案是限制一次只能一个线程操作。更为完善点,万一一瞬间有10000条对同一用户进行操作的请求到来,可以使用redis进行标记,加入有线程进入了,其它请求驳回。具体实现如下

			Jedis jedis = getJedis();
			
			//0不占用 1占用
			if (jedis.get(userId + "") == null || jedis.get(userId + "").equals("0")) {
				jedis.set(userId + "", "1");
			} else if (jedis.get(userId + "").equals("1")) {
				ServletUtilsEx.renderJson(response, new Result(Result.FAIL, "处理中,请稍后", null));
          		return;
			} else {
				ServletUtilsEx.renderJson(response, new Result(Result.FAIL, "failure", null));
          		return;
			}
			
			synchronized (this) {
				User user = new User();
				user.setId(userId);
				user = userService.getUser(user);
				
				if (user != null) {
					
					//1.判断提现金额是否超过余额
					
					//2.减去余额
				}
			}
			
			jedis.set(userId + "", "0");
			RedPackageUtils.returnResource(jedis);

			//3.微信提现

这是在代码层面就行加锁,也可以在数据库层面进行控制。

select .. for update

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值