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, "未知错误");
}
}