Redisson介绍: https://github.com/redisson/redisson/wiki
Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象,Redisson、Jedis、Lettuce是三个不同的操作 Redis 的客户端,Jedis、Lettuce 的 API 更侧重对Reids 数据库的CRUD(增删改查),而Redisson API 侧重于分布式开发。
在pom.xml中加入相关依赖:
<!--redisson--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.17.2</version> </dependency> |
编写Redis分布式锁工具类
创建包utils并创建工具类RedissonLockUtils
package com.ss.demo.utils; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * 分布式所 */ @Slf4j @Component public class RedissonLockUtils { @Autowired private RedissonClient redissonClient; /** * 上锁 * @param lockName * @return */ public Boolean lock(String lockName) { //判断客户端是否存在 if(redissonClient == null) { log.info("RedissonLock is null"); return false; } try { //加锁 RLock lock = redissonClient.getLock(lockName); //过期时间为10秒钟 //这里无需手动解锁,到10秒钟会自动解锁 lock.lock(10, TimeUnit.SECONDS); return true; }catch (Exception e) { e.printStackTrace(); return false; } } /** * 解锁 * @param lockName * @return */ public Boolean unLock(String lockName) { //判断客户端是否存在 if(redissonClient == null) { log.info("RedissonLock is null"); return false; } try { //获得那把锁 RLock lock = redissonClient.getLock(lockName); lock.unlock(); //解锁 return true; }catch (Exception e) { e.printStackTrace(); return false; } } } |
然后修改service的接口ITOrderService
package com.ss.demo.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ss.demo.domain.TOrder;
/** * <p> * 服务类 * </p> */ public interface ITOrderService extends IService<TOrder> { /** * 创建订单方法 * @param productId * @param count * @return */ String createOrder(Integer productId, Integer count); /** * 使用悲观锁进行实现 * @param productId * @param count * @return */ String createOrderPessimisticlock(Integer productId, Integer count); /** * 乐观锁 * @param productId * @param count * @return */ String createOrderOptmisticlock(Integer productId, Integer count); /** * Redis操作 * @param productId * @param count * @return */ String createOrderRedis(Integer productId, Integer count); /** * Redisson操作 * @param productId * @param count * @return */ String createOrderRedisson(Integer productId, Integer count); } |
修改service的实现类TOrderServiceImpl
//引入redisson工具类进行上锁和解锁的操作
@Autowired
private RedissionUtils redissonLockUtils;
/**
* redisson
* @param productId
* @param count
* @return
*/
@Override
public String createOrderRedisson(Integer productId, Integer count) {
//加锁操作
String key = "lock:";
Boolean lock = redissonLockUtils.lock(key + productId); //上锁
//是否获得了锁
if(!lock) { //如果未获得锁
return "未获得锁";
}
try {
//根据商品id获取商品信息
Product product = productMapper.selectById(productId);
if(product == null) {
throw new RuntimeException("购买商品不存在");
}
log.info(Thread.currentThread().getName() +"库存数量" + product.getCount());
//校验库存
if(count > product.getCount()) {
throw new RuntimeException("库存不足");
}
//更新库存
product.setCount(product.getCount() - count);
//更新操作
productMapper.updateById(product);
//创建订单操作
TOrder order = new TOrder();
order.setOrderStatus(1);
order.setReceiverName("张三");
order.setReceiverMobile("12345678765");
//设置订单价格【商品单价*商品数量】
order.setOrderAmount(product.getPrice().multiply(new BigDecimal(count)));
orderMapper.insert(order); //插入订单操作
//创建订单商品表的操作
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId()); //订单Id
orderItem.setProduceId(product.getId()); //商品Id
orderItem.setPurchasePrice(product.getPrice()); //购买价格
orderItem.setPurchaseNum(count); //购买数量
orderItemMapper.insert(orderItem);
return order.getId();
} catch (Exception e) {
e.printStackTrace();
} finally {
redissonLockUtils.unlock(key + productId);
}
return "失败";
} |
修改controller:TOrderController
package com.ss.demo.controller; import com.ss.demo.service.ITOrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 前端控制器 * </p> */ @RestController @RequestMapping("/order") public class TOrderController { @Autowired private ITOrderService orderService;
@PostMapping("/create") public String createOrder(Integer productId, Integer count) { //return orderService.createOrder(productId, count); //return orderService.createOrderRedis(productId,count); return orderService.createOrderRedisson(productId, count); } } |
启动服务9091,9090
使用Jmeter记性测试
把数据库所有数据复原
测试略过