课堂笔记20230825

亮子 2023-08-25 09:20:20 10300 0 0 0

分布式锁的使用

1、添加依赖

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.16.2</version>
        </dependency>

2、注入对象

    @Autowired
    RedissonClient redissonClient;

3、使用分布式锁

    /**
     * @description 分布式锁,要放到分布式事务的外面
     * @author 军哥
     * @date 2023/8/25 17:13
     * @version 1.0
     */
    @Override
    public ResultVo buyProduct(OrderVo orderVo) {
        RLock rLock = redissonClient.getLock("ORDER_MAKE");
        try {
            rLock.lock();

            return makeOrder(orderVo);

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }

        return ResultVo.FAILED(501, "未知错误");
    }

注意事项:分布式锁,要放到分布式事务的外面

订单接口代码

package com.bw2102a.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bw2102a.domain.ResultVo;
import com.bw2102a.mapper.TbOrderDetailMapper;
import com.bw2102a.mapper.TbOrderMapper;
import com.bw2102a.mapper.TbStockMapper;
import com.bw2102a.pojo.ProductDetail;
import com.bw2102a.pojo.TbOrder;
import com.bw2102a.pojo.TbOrderDetail;
import com.bw2102a.pojo.TbStock;
import com.bw2102a.service.ProductDetailService;
import com.bw2102a.mapper.ProductDetailMapper;
import com.bw2102a.vo.common.PageVo;
import com.bw2102a.vo.product.OrderVo;
import com.bw2102a.vo.product.ProductDetailVo;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

/**
* @author 86134
* @description 针对表【tb_product_detail(商品明细表)】的数据库操作Service实现
* @createDate 2023-08-22 20:31:48
*/
@Service
public class ProductDetailServiceImpl extends ServiceImpl<ProductDetailMapper, ProductDetail>
    implements ProductDetailService{

    @Autowired
    ProductDetailMapper productDetailMapper;

    @Autowired
    TbStockMapper tbStockMapper;

    @Autowired
    TbOrderMapper tbOrderMapper;

    @Autowired
    TbOrderDetailMapper tbOrderDetailMapper;

    @Autowired
    RedissonClient redissonClient;

    @Override
    public ResultVo listDetailByPage(PageVo pageVo) {
        Page<ProductDetail> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());


        Page<ProductDetail> productDetailPage = productDetailMapper.selectPage(page,
                new QueryWrapper<ProductDetail>().lambda().orderByDesc(ProductDetail::getProductDetailId)
        );

        return ResultVo.SUCCESS(productDetailPage);
    }

    @GlobalTransactional
    private ResultVo makeOrder(OrderVo orderVo) {
        //--1 查询商品是否存在
        //--2 查询库存是否够
        List<ProductDetailVo> details = orderVo.getDetails();
        Long amount = 0L;

        for (ProductDetailVo detail : details) {
            // 查询商品
            ProductDetail one = productDetailMapper.selectOne(
                    new QueryWrapper<ProductDetail>().lambda().eq(ProductDetail::getSkuId, detail.getSku())
            );
            if(one == null) {
                return ResultVo.FAILED(404, "商品不存在");
            }
            amount += (one.getPrice()*detail.getCount());

            // 查询库存
            TbStock tbStock = tbStockMapper.selectOne(
                    new QueryWrapper<TbStock>().lambda().eq(TbStock::getSkuId, detail.getSku())
            );
            if(tbStock == null || tbStock.getCounts() < detail.getCount()) {
                return ResultVo.FAILED(404, "商品库存不足");
            }
        }



        //--3 扣减库存
        for (ProductDetailVo detail : details) {
            TbStock tbStock = tbStockMapper.selectOne(
                    new QueryWrapper<TbStock>().lambda().eq(TbStock::getSkuId, detail.getSku())
            );

            tbStock.setCounts(tbStock.getCounts() - detail.getCount());
            tbStock.setUpdateTime(null);

            tbStockMapper.updateById(tbStock);
        }

        //--4 保存订单
        TbOrder tbOrder = new TbOrder();
        tbOrder.setUserId(orderVo.getUserId());
        tbOrder.setAmount(amount);
        String orderNo = UUID.randomUUID().toString();
        tbOrder.setOrderNo(orderNo);

        tbOrderMapper.insert(tbOrder);

        // 生成订单的明细
        for (ProductDetailVo detail : details) {
            // 查询商品
            ProductDetail one = productDetailMapper.selectOne(
                    new QueryWrapper<ProductDetail>().lambda().eq(ProductDetail::getSkuId, detail.getSku())
            );

            TbOrderDetail tbOrderDetail = new TbOrderDetail();
            tbOrderDetail.setOrderId(tbOrder.getOrderId());

            tbOrderDetail.setDetailId(one.getProductDetailId());
            tbOrderDetail.setDetailName(one.getDetailName());

            tbOrderDetail.setPrice(one.getPrice());
            tbOrderDetail.setCount(detail.getCount());
            tbOrderDetail.setAmount(one.getPrice()*detail.getCount());

            tbOrderDetailMapper.insert(tbOrderDetail);

        }

        return ResultVo.SUCCESS();
    }

    /**
     * @description 分布式锁,要放到分布式事务的外面
     * @author 军哥
     * @date 2023/8/25 17:13
     * @version 1.0
     */
    @Override
    public ResultVo buyProduct(OrderVo orderVo) {
        RLock rLock = redissonClient.getLock("ORDER_MAKE");
        try {
            rLock.lock();

            return makeOrder(orderVo);

        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }

        return ResultVo.FAILED(501, "未知错误");
    }
}