日常小记:订单添加锁机制

        考虑情况:java是个多线程机制。多线程是一把双刃剑,一旦设计到多个线程操作共享资源的情况下,处理不好就会出现线程安全问题。线程安全性可能是非常复杂的,在沒有充足的同步情况下,多个线程执行顺序是不好操作的。

        同步和异步: 同步就是一件事,一件事情一件事的做。异步就是,做一件事情,不引响做其他事情。

        应用场景:用户下订单的时候考虑到并发情况。商品购买是有库存的,一个用户可以购买商品数量为多个,如多个用户同时下单可能会产生商品不够,但订单生成成功问题。

        解决办法:采用乐观锁解决,商品表中添加一个冻结数量字段和一个数据版本字段

            

        下订单之前先获取当前商品信息。

            加锁:

// 查询当前商品信息
// 【乐观锁】获取版本
ULCommodityTg dbCommodityTg = ulCommodityTGDao.selectById(orderSubmitPO.getCommodityId());
	if (dbCommodityTg == null) {
		bo.setOrderInfo(ULApiResultTips.Order.ORDER_ERROR);
		return new ULResult<CResultOrderInfoBO>(bo);
	}
boolean flag = false;
for (int i = 0; i < 3; i++) {
	// 使用当前数据版本,追加冻结数量
	Integer happyLock = ulCommodityTGDao.updateByHappyLock(dbCommodityTg.getId(),
	        dbCommodityTg.getDataVersion(), orderSubmitPO.getQuantity());
		if (happyLock > 0) {
			flag = true;
			break;
		}
		Thread.sleep(1000);
		// 重新获取版本,再次尝试下单
		dbCommodityTg = ulCommodityTGDao.selectById(orderSubmitPO.getCommodityId());
	}
	// 数据版本已增加,当前订单更新失败
	if (!flag) {
		bo.setOrderInfo(ULApiResultTips.Order.ORDER_OVERFLOW);
		return new ULResult<CResultOrderInfoBO>(bo);
	}

    根据版本号判断当前下单用户。

解锁:

ULShop dbShop = ulShopDao.selectById(dbOrder.getShopId());
		// 商铺销售量加一
		dbShop.setSalesVolume(dbShop.getSalesVolume() + 1);
		dbShop.setUpdateTime(now);
		ulShopDao.updateByPrimaryKeySelective(dbShop);

		// 团购 美食
		if (ULOrderJumpTypeEmun.TG_FOOD.getType().equals(dbOrder.getJumpType())) {
			// 加销量、减冻结数量
			List<ULOrderFood> dbFoods = ulOrderFoodDao.selectByProperty("orderNo", orderNo);
			ULCommodityTg dbCommodity = ulCommodityTGDao.selectById(dbFoods.get(0).getCommodityId());
			dbCommodity.setSalesFreeze(dbCommodity.getSalesFreeze() - dbOrder.getQuantity());
			dbCommodity.setSalesQuantity(dbCommodity.getSalesQuantity() + dbOrder.getQuantity());
			// 添加销量
			dbCommodity.setSalesQuantity(dbCommodity.getSalesQuantity() + dbFoods.size());
			dbCommodity.setUpdateTime(now);
			ulCommodityTGDao.updateByPrimaryKeySelective(dbCommodity);
		}

至此:乐观锁添加完成,保证了用户购买的数量不能超过当前库存。

猜你喜欢

转载自my.oschina.net/dzsgwz/blog/1795143