分布式环境下如何保证 商品不出现超卖

在分布式环境下解决商品不出现超卖的关键就说对上面每一笔库存在进行操作的时候需要进行锁,然后进行扣减,并且释放锁:

上关键代码:

	@ServiceLock(lockKey="Commodity")
	@Transactional
	public void killHandler() {
		int stachId = 1;//库存编号
		int stachNum = stachModel.getStachNum(stachId);//查看库存是否足够
		if(stachNum > 0) {//库存充足
			stachNum -= 1; //每次购买一件

			Map<String,Object> inserParam = new HashMap();
			inserParam.put("id", Math.random() * 100000000);
			inserParam.put("num", 1);
			inserParam.put("stachid", stachId);
			inserParam.put("version", 0);
			orderModel.insert(inserParam);

			stachModel.modelNum(stachId, stachNum);
		}
	}

关键核心是:上分布式锁

	@Around("@annotation(com.sloth.kill.annotaion.ServiceLock)")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();

		if (method.isAnnotationPresent(ServiceLock.class)) {
			ServiceLock annotation = method.getAnnotation(ServiceLock.class);
			String lockKey = annotation.lockKey();
			log.info(lockKey);
			RLock lock = redissonClient.getLock(lockKey);
			Object obj = null;
			try{
				lock.lock();
				obj = joinPoint.proceed();
			}catch(Throwable e){
				e.printStackTrace();
				throw new Throwable(e);
			}finally{
				lock.unlock();
			}
			return obj;	

		}else {
			return joinPoint.proceed();
		}

	}

升级为 注解读取参数输入内容

@Around("@annotation(com.sy.store.annotation.LockAnnotation)")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();

		if (method.isAnnotationPresent(LockAnnotation.class)) {
			Parameter[] parameters =  method.getParameters();
			LockAnnotation annotation = method.getAnnotation(LockAnnotation.class);
			EvaluationContext ctx = new StandardEvaluationContext();
			if(parameters != null && parameters.length > 0) {
				for (int i = 0; i < parameters.length; i++) {
					ctx.setVariable(parameters[i].getName(), joinPoint.getArgs()[i]);
				}
			}
			ExpressionParser parser = new SpelExpressionParser();
			StandardEvaluationContext context = new StandardEvaluationContext();  
			context.setBeanResolver(new BeanFactoryResolver(applicationContext)); 
			Object value = parser.parseExpression(annotation.value()).getValue(ctx);
			RLock lock = redissonClient.getLock(value.toString());
			Object obj = null;
			try{
				lock.lock();
				obj = joinPoint.proceed();
			}catch(Throwable e){
				e.printStackTrace();
				throw new Throwable(e);
			}finally{
				lock.unlock();
			}
			return obj;	

		}
		return joinPoint.proceed();

	}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树懒_Zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>