介绍redis分布式锁


本文摘自PHP中文网,作者coldplay.xixi,侵删。

推荐(免费):redis

Redisson

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

  1. redisson未获取到锁的会进入等待,直到获取到锁。
  2. 另外两种方式如果未获取到锁,会放弃,不会执行业务代码。

1

2

3

4

<dependency>

    <groupId>org.redisson</groupId>

    <artifactId>redisson-spring-boot-starter</artifactId>

    <version>3.13.6</version></dependency>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@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)

1

2

3

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-data-redis</artifactId></dependency>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

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);

    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@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)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

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();

    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@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分布式锁的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

介绍redis分布式锁

更多相关阅读请进入《redis分布式锁》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...