• 技术文章 >数据库 >Redis

    介绍redis分布式锁

    coldplay.xixicoldplay.xixi2021-02-20 09:54:58转载65

    推荐(免费):redis

    Redisson

    redisson和下列一下自行封装两种方式的区别(场景):

    1. redisson未获取到锁的会进入等待,直到获取到锁。
    2. 另外两种方式如果未获取到锁,会放弃,不会执行业务代码。
    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson-spring-boot-starter</artifactId>
        <version>3.13.6</version></dependency>
    @Autowiredprivate Redisson redisson;@GetMapping("/redissonLock")public String redissonLock() {
        log.info("进入了方法");
        RLock lock = redisson.getLock("redissonLock");
        try {
            lock.lock(30, TimeUnit.SECONDS);
            Thread.sleep(10000);
            System.out.println("我是你大哥");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        // 如果不释放,不会唤起其他线程,则其他线程会超时过期自动唤醒,不会执行业务代码
            lock.unlock();
        }
        return "运行结束";}

    RedisTemplate封装redis锁(1)

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId></dependency>
    package com.util;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.connection.RedisStringCommands;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.script.RedisScript;import org.springframework.data.redis.core.types.Expiration;import org.springframework.stereotype.Component;import java.util.Arrays;@Componentpublic class RedisLock {
    
        private static RedisTemplate redisTemplate;
    
        private static String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n" +
                "\treturn redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "   \treturn 0\t\n" +
                "end  ";
    
        public RedisLock(RedisTemplate redisTemplate) {
            RedisLock.redisTemplate = redisTemplate;
        }
    
        public static Boolean getLock(String key, String value, Long expireTime) {
            RedisStringCommands.SetOption setOption = RedisStringCommands.SetOption.ifAbsent();
            Expiration expiration = Expiration.seconds(expireTime);
            RedisCallback<Boolean> booleanRedisCallback = new RedisCallback<Boolean>() {
                @Override
                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                    return connection.set(redisTemplate.getKeySerializer().serialize(key), redisTemplate.getValueSerializer().serialize(value), expiration, setOption);
                }
            };
            return (Boolean) redisTemplate.execute(booleanRedisCallback);
        }
    
        public static Boolean unLock(String key, String value) {
            RedisScript<Boolean> redisScript = RedisScript.of(script, Boolean.class);
            return (Boolean) redisTemplate.execute(redisScript, Arrays.asList(key), value);
        }}
    @GetMapping("/redisLock")public String redisLock() {
        log.info("进入了方法");
        String key = "redisLock";
        String uuid = UUID.randomUUID().toString();
        try {
            if (RedisLock.getLock(key, uuid, 30L)) {
                log.info("进入了锁");
                Thread.sleep(10000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            RedisLock.unLock(key, uuid);
        }
        log.info("方法执行完成");
        return "程序结束";}

    RedisTemplate封装redis锁(2)

    package com.util;import lombok.extern.slf4j.Slf4j;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.connection.RedisStringCommands;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.script.RedisScript;import org.springframework.data.redis.core.types.Expiration;import java.util.Arrays;import java.util.UUID;@Slf4jpublic class HighRedisLock implements AutoCloseable{
    
        private RedisTemplate redisTemplate;
    
        private String key;
    
        private String value;
    
        private Long expireTime;
    
        private static String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n" +
                "\treturn redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "   \treturn 0\t\n" +
                "end  ";
    
        public HighRedisLock(RedisTemplate redisTemplate, String key, Long expireTime) {
            this.redisTemplate = redisTemplate;
            this.key = key;
            this.value = UUID.randomUUID().toString();
            this.expireTime = expireTime;
        }
    
        public Boolean getLock() {
            RedisStringCommands.SetOption setOption = RedisStringCommands.SetOption.ifAbsent();
            Expiration expiration = Expiration.seconds(expireTime);
            RedisCallback<Boolean> booleanRedisCallback = new RedisCallback<Boolean>() {
                @Override
                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                    return connection.set(redisTemplate.getKeySerializer().serialize(key), redisTemplate.getValueSerializer().serialize(value), expiration, setOption);
                }
            };
            return (Boolean) redisTemplate.execute(booleanRedisCallback);
        }
    
        public Boolean unLock() {
            RedisScript<Boolean> redisScript = RedisScript.of(script, Boolean.class);
            return (Boolean) redisTemplate.execute(redisScript, Arrays.asList(key), value);
        }
    
        @Override
        public void close() throws Exception {
            unLock();
        }}
    @Autowiredprivate RedisTemplate redisTemplate;@GetMapping("/highRedisLock")public String highRedisLock() {
        log.info("进入了方法");
        try (HighRedisLock redisLock = new HighRedisLock(redisTemplate, "highRedisLock", 30L)) {
            if (redisLock.getLock()) {
                log.info("进入了锁");
                Thread.sleep(10000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("方法执行完成");
        return "程序结束";}

    以上就是介绍redis分布式锁的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:CSDN,如有侵犯,请联系a@php.cn删除
    专题推荐:redis分布式锁
    上一篇:总结Redis常用数据类型操作指令 下一篇:如何实时监控redis性能
    第15期线上培训班

    相关文章推荐

    • 深入分析Redis• redis讲解分布式数据库CAP原理• redis中的几种常用基础对象介绍• redis事件处理流程分析• 总结Redis常用数据类型操作指令

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网