SpringBoot之使用Redisson实现分布式锁(秒杀系统)

前面讲完了Redis的分布式锁的实现,接下来讲Redisson的分布式锁的实现,一般提及到Redis的分布式锁我们更多的使用的是Redisson的分布式锁,Redis的官方也是建议我们这样去做的。Redisson点我可以直接跳转到Redisson的官方文档。

1.1、引入Maven依赖

       

 <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.5.0</version>
        </dependency>


如果你引入的就是redisson的依赖包,如果该依赖包的版本低于3.5会需要你再引入

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.25.Final</version>
</dependency>
 
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
 
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>


这样的一些依赖。

1.2、配置redis信息

spring:
  application:
    name: spring-cloud-product
redisson:
  address: redis://localhost:6379
  password: web2017

1.3、写一个RedissonConfig配置类 来配置你的redisson

/**
 * @Description //TODO
 * @Date 2020/3/19 22:32
 * @Author huangwb
 **/
@Configuration
public class RedissonAutoConfiguration {
 
    @Value("${redisson.address}")
    private String addressUrl;
    @Value("${redisson.password}")
    private String password;
 
    /**
     * @return org.redisson.api.RedissonClient
     * @Author huangwb
     * @Description //TODO 单机模式配置
     * @Date 2020/3/19 22:54
     * @Param []
     **/
    @Bean
    public RedissonClient getRedisson() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress(addressUrl).setPassword(password)
                .setReconnectionTimeout(10000)
                .setRetryInterval(5000)
                .setTimeout(10000)
                .setConnectTimeout(10000);
        return Redisson.create(config);
    }
    /**
     * @return  
     * @Author huangwb
     * @Description //TODO 主从模式
     * @Date  20203/19 10:54
     * @Param 
     * 
     **/
   /* @Bean
    public RedissonClient getRedisson() {
        RedissonClient redisson;
        Config config = new Config();
        config.useMasterSlaveServers()
                //可以用"rediss://"来启用SSL连接
                .setMasterAddress("redis://***(主服务器IP):6379").setPassword("web2017")
                .addSlaveAddress("redis://***(从服务器IP):6379")
                .setReconnectionTimeout(10000)
                .setRetryInterval(5000)
                .setTimeout(10000)
                .setConnectTimeout(10000);//(连接超时,单位:毫秒 默认值:3000);
               
        //  哨兵模式config.useSentinelServers().setMasterName("mymaster").setPassword("web2017").addSentinelAddress("***(哨兵IP):26379", "***(哨兵IP):26379", "***(哨兵IP):26380");
        redisson = Redisson.create(config);
        return redisson;
    }*/
}


1.4、编写一个秒杀接口

 

@Autowired
private RedissonClient redissonClient;
 
@Override
public boolean decrementProductStore(Long productId, Integer productQuantity) {
    String key = "dec_store_lock_" + productId;
    RLock lock = redissonClient.getLock(key);
    try {
        //加锁 操作很类似Java的ReentrantLock机制
        lock.lock();
        ProductInfo productInfo = productInfoMapper.selectByPrimaryKey(productId);
        //如果库存为空
        if (productInfo.getProductStock() == 0) {
           return false;
        }
        //简单减库存操作 没有重新写其他接口了
        productInfo.setProductStock(productInfo.getProductStock() - 1);
        productInfoMapper.updateByPrimaryKey(productInfo);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    } finally {
        //解锁
        lock.unlock();
    }
    return true;
}


1.5、写一个简单的测试请求 

@GetMapping("test")
public String createOrderTest() {
    if (!productInfoService.decrementProductStore(1L, 1)) {
        return "库存不足";
    }
    OrderMaster orderMaster = new OrderMaster();
    //未支付
    orderMaster.setOrderStatus(0);
    //未支付
    orderMaster.setPayStatus(0);
    orderMaster.setBuyerName(name);
    orderMaster.setBuyerAddress("湖南长沙");
    orderMaster.setBuyerPhone("18692794847");
    orderMaster.setOrderAmount(BigDecimal.ZERO);
    orderMaster.setCreateTime(DateUtils.getCurrentDate());
    orderMaster.setOrderId(UUID.randomUUID().toString().replaceAll("-", ""));
    orderMasterService.insert(orderMaster);
    return "创建订单成功";
}


1.6、使用ab做接口测试

ab -n 300 -c 300 请求地址

-n 的含义就是你做多少个请求

-c 的含义就是多少个用户并发请求

数据库中的商品已经全部被秒杀完 并未出现超库存的情况。

原文链接:https://blog.csdn.net/qq_37892957/article/details/89337943

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值