redis的使用场景-分布式锁

8 篇文章 0 订阅
5 篇文章 0 订阅

使用redis的setnx命令放入数据并用此数据当锁完成业务(但是如果用户操作途中出现异常导致超出指定时间会出现问题)

@Service
public class StockService {

    @Autowired
    private StockDao stockDao;	//mapper注入
    @Autowired
    private StringRedisTemplate redisTemplate;	//使用redis方法
    //
    public String decrement(Integer productid) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        //1.获取共享锁资源(通过进行redis放入数据的方式,如果放入成功说明redis没有该数据)
        Boolean flag = opsForValue.setIfAbsent("product::" + productid, "1111", 30, TimeUnit.SECONDS);
        //表示获取锁成功
        if(flag) {
            try {
                //根据id查询商品的库存
                int num = stockDao.findById(productid);
                if (num > 0) {
                    //修改库存
                    stockDao.update(productid);
                    System.out.println("商品编号为:" + productid + "的商品库存剩余:" + (num - 1) + "个");
                    return "商品编号为:" + productid + "的商品库存剩余:" + (num - 1) + "个";
                } else {
                    System.out.println("商品编号为:" + productid + "的商品库存不足。");
                    return "商品编号为:" + productid + "的商品库存不足。";
                }
            }finally {
                //释放锁资源(删除放入的该数据,然后准备开始下一次抢锁)
                redisTemplate.delete("product::"+productid);
            }
        }else{
            //休眠100毫秒 在继续抢锁
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return decrement(productid);
        }
    }
}

看门狗(改善版,解决了超时的bug)

引入依赖

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

编写配置类

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redisson(){
        Config config = new Config();
        //连接redis集群
        config.useClusterServers()
         use "rediss://" for SSL connection
        .addNodeAddress("redis://127.0.0.1:7181","","","");
        //连接单机
        config.useSingleServer().setAddress("redis://192.168.111.188:6379");
        RedissonClient redisson = Redisson.create(config);
        return redisson;
    }
}

业务代码

@Service
public class StockService {

    @Autowired
    private StockDao stockDao;	//注入mapper
    @Autowired
    private RedissonClient redisson;	//注入看门狗

    //
    public String decrement(Integer productid) {
        RLock lock = redisson.getLock("product::" + productid);	//获取锁资源
        lock.lock();	//上锁
        try {
            //根据id查询商品的库存: 提前预热到redis缓存中
            int num = stockDao.findById(productid);
            if (num > 0) {
                //修改库存---incr---定时器[redis  数据库同步]
                stockDao.update(productid);
                System.out.println("商品编号为:" + productid + "的商品库存剩余:" + (num - 1) + "个");
                return "商品编号为:" + productid + "的商品库存剩余:" + (num - 1) + "个";
            } else {
                System.out.println("商品编号为:" + productid + "的商品库存不足。");
                return "商品编号为:" + productid + "的商品库存不足。";
            }
        }finally {
            lock.unlock();	//释放锁资源
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值