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

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Component;

import org.springframework.util.StringUtils;

  

@Component

public class RedisLock {

  

    Logger logger = LoggerFactory.getLogger(this.getClass());

  

    @Autowired

    private StringRedisTemplate redisTemplate;

  

    /**

     * 加锁

     * @param key  

     * @param value 当前时间 + 超时时间

     * @return

     */

    public boolean lock(String key, String value) {

     

        if (redisTemplate.opsForValue().setIfAbsent(key, value)) {    

            // 这个其实就是setnx命令,只不过在java这边稍有变化,返回的是boolean

            // 设置个过期时间,当然如果在这中间的空隙过程中如果有特殊因素导致指令无法继续,也会导致死锁的产生,如果死锁出现,则后续代码会处理

            redisTemplate.expire(key, lockTime, TimeUnit.SECONDS);

            return true;

        }

  

        // 避免死锁,且只让一个线程拿到锁

        String currentValue = redisTemplate.opsForValue().get(key);

        // 如果锁过期了

        if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) {

            //获取上一个锁的时间

            String oldValues = redisTemplate.opsForValue().getAndSet(key, value);

  

            /*

               只会让一个线程拿到锁

               如果旧的value和currentValue相等,只会有一个线程达成条件,因为第二个线程拿到的oldValue已经和currentValue不一样了

             */

            if (!StringUtils.isEmpty(oldValues) && oldValues.equals(currentValue)) {

                return true;

            }

        }

        return false;

    }

  

  

    /**

     * 解锁

     * @param key

     * @param value

     */

    public void unlock(String key, String value) {

        try {

            String currentValue = redisTemplate.opsForValue().get(key);

            if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) {

                redisTemplate.opsForValue().getOperations().delete(key);

            }

        } catch (Exception e) {

            logger.error("redis分布式锁解锁异常,{}", e);

        }

    }

}

调用:

1

2

3

4

5

6

7

8

9

10

11

12

13

//加锁

   long time = System.currentTimeMillis() + 1000 * lockTime //超时时间:10秒,最好设为常量

 

   boolean isLock = redisLock.lock(...keyName, String.valueOf(time));

   if(!isLock){

       throw new RuntimeException("系统正忙");

   }

    

   // doSomething...

    

    

   //解锁

   redisLock.unlock(...keyName, String.valueOf(time));

更多Redis相关知识,请访问Redis使用教程栏目!

以上就是redis会发生死锁问题吗的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

redis会发生死锁问题吗

更多相关阅读请进入《redis会发生死锁吗》频道 >>


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

数据库系统概念 第6版

机械工业出版社

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



打赏

取消

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

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

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

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

评论

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