Daily Notes: Order Add Lock Mechanism

        Consideration: Java is a multi-threading mechanism. Multithreading is a double-edged sword. Once it is designed to operate on shared resources with multiple threads, if it is not handled properly, there will be thread safety issues. Thread safety can be very complex, and the order of execution of multiple threads does not work well without adequate synchronization.

        Synchronous and Asynchronous: Synchronization is one thing, one thing to one thing to do. Asynchronous is, do one thing, do other things without triggering.

        Application scenario: Consider concurrency when users place an order. Commodity purchases are in stock, and a user can purchase multiple products. For example, if multiple users place an order at the same time, there may be insufficient products, but the order generation is successful.

        Solution: use optimistic locking to solve the problem, add a frozen quantity field and a data version field to the commodity table

            

        Get current product information before placing an order.

            Lock:

// 查询当前商品信息
// 【乐观锁】获取版本
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);
	}

    Determine the current order user based on the version number.

Unlock:

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);
		}

So far: the optimistic lock is added, which ensures that the quantity purchased by the user cannot exceed the current inventory.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325092548&siteId=291194637