redis分布式锁

一、简述

二、存在问题

1、死锁、原子性问题

2、业务执行时间超时

3、锁误删

4、锁续命

三、解决措施

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
             <groupId>org.redisson</groupId>
             <artifactId>redisson</artifactId>
             <version>3.11.1</version>
        </dependency>
    </dependencies>
redission配置类

@Configuration
public class RedissionConfig {
    @Bean
    public Redisson getRedission(){

        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379").setPassword("root");
        Redisson redisson = (Redisson) Redisson.create(config);
        return redisson;
    }
}

1、

public String deductStock() {

        String lockKey = "lockKey";

        //当前线程唯一标识  防止误删其他线程的措
        String clientId = UUID.randomUUID().toString();

        try {
            //设置锁  原子性和死锁
            Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);


           /*
           Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    Long expire = redisTemplate.getExpire(lockKey, TimeUnit.SECONDS);
                    if(expire < 3){
                        redisTemplate.expire(lockKey,10,TimeUnit.SECONDS);
                    }
                };
            },5);
            */

            if(!result){
                return "error code";
            }

            int stockNum = Integer.parseInt(redisTemplate.opsForValue().get("stock"));

            if (stockNum > 0) {
                int realStock = stockNum - 1;
                redisTemplate.opsForValue().set("stock",realStock+"");
                System.out.println("扣减库存成功,剩余库存为:"+realStock);
            } else {
                System.out.println("扣减库存失败");
            }
        } finally {
            // 释放锁  防止死锁
            if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
                redisTemplate.delete(lockKey);
            }
        }

        return "ok";
    }

2、

@GetMapping("/deductStock")
    public String deductStock() {

        String lockKey = "lockKey";

        //当前线程唯一标识  防止误删其他线程的措
        String clientId = UUID.randomUUID().toString();

        RLock lock = redisson.getLock(lockKey);
        try {
     lock.lock();

            int stockNum = Integer.parseInt(redisTemplate.opsForValue().get("stock"));

            if (stockNum > 0) {
                int realStock = stockNum - 1;
                redisTemplate.opsForValue().set("stock",realStock+"");
                System.out.println("扣减库存成功,剩余库存为:"+realStock);
            } else {
                System.out.println("扣减库存失败");
            }
        } finally {
            // 释放锁  防止死锁
            if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
                redisTemplate.delete(lockKey);
            }
        }

        return "ok";
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值