介紹redis分布式鎖

介紹redis分布式鎖

推薦(免費):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] thenn" +             "treturn redis.call("del",KEYS[1])n" +             "elsen" +             "   treturn 0tn" +             "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] thenn" +             "treturn redis.call("del",KEYS[1])n" +             "elsen" +             "   treturn 0tn" +             "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 "程序結束";}

? ? ??

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享