redis分布式锁

Redisson

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

  1. redisson未获取到锁的会进入等待,直到获取到锁。
  2. 另外两种方式如果未获取到锁,会放弃,不会执行业务代码。
<dependency>
    <groupId>org.redissongroupId>
    <artifactId>redisson-spring-boot-starterartifactId>
    <version>3.13.6version>
dependency>
@Autowired
private 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.bootgroupId>
   <artifactId>spring-boot-starter-data-redisartifactId>
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;

@Component
public 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;

@Slf4j
public 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();
    }
}

@Autowired
private 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 "程序结束";
}

你可能感兴趣的:(java,非关系型数据库,redis,java,redisson)