博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis分布式锁
阅读量:6572 次
发布时间:2019-06-24

本文共 2691 字,大约阅读时间需要 8 分钟。

hot3.png

项目需要redis 分布式所以自己封装了一套

 

 

package com.Tourism;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import com.Tourism.timed.task.OrderTask;

import java.util.Random;

import java.util.concurrent.TimeUnit;

public class RedisUtils {

    private static final Logger LOGGER = Logger.getLogger(RedisUtils.class);

    public static final String REDIS_LOCK = "RedisLock:";

    private static final long DEFAULT_WAIT_LOCK_TIME_OUT = 60;// 60s 有慢sql,超时时间设置长一点

    private static final long DEFAULT_EXPIRE = 80;// 80s 有慢sql,超时时间设置长一点
    private String key;
    @Autowired
    private RedisTemplate redisTemplate;

    /**

     * 等待锁的时间,单位为s
     *
     * key
     * timeout s
     * seconds
     */
    public boolean lock(String key, long timeout, TimeUnit seconds,String value) {
        String lockKey = generateLockKey(key);
        long nanoWaitForLock = seconds.toNanos(timeout);
        long start = System.nanoTime();

        try {

            while ((System.nanoTime() - start) < nanoWaitForLock) {
                if (redisTemplate.getConnectionFactory().getConnection().setNX(lockKey.getBytes(), value.getBytes())) {
                    redisTemplate.expire(lockKey, DEFAULT_EXPIRE, TimeUnit.SECONDS);// 暂设置为80s过期,防止异常中断锁未释放
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("add RedisLock["+key+"]."+ Thread.currentThread());
                    }
                    return true;
                }
                TimeUnit.MILLISECONDS.sleep(1000 + new Random().nextInt(100));// 加随机时间防止活锁
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            unlock(key,value);
        }
        return false;
    }

    public void unlock(String key,String value) {

        try {
            String lockKey = generateLockKey(key);
            RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
            Object object = redisTemplate.opsForValue().get("key");
            if(object == null||!object.toString().equals(value)) {
                return ;
            }
            connection.del(lockKey.getBytes());
            connection.del(key.getBytes());
            connection.close();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    private String generateLockKey(String key) {

        return String.format(REDIS_LOCK + "%s", key);
    }

    

    public void close() {

        try {
            String lockKey = generateLockKey(key);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("release RedisLock[" + lockKey + "].");
            }
            RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
            connection.del(lockKey.getBytes());
            connection.close();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

}

 

转载于:https://my.oschina.net/u/1261887/blog/1837715

你可能感兴趣的文章
从pandas到geopandas
查看>>
LOL设计模式之「策略模式」
查看>>
用express搭建网站
查看>>
如何在 Swift 中进行错误处理
查看>>
[Leetcode] Factor Combinations 因数组合
查看>>
用tinypng插件创建gulp task压缩图片
查看>>
浅谈DOMContentLoaded事件及其封装方法
查看>>
BetaMeow----利用机器学习做五子棋AI
查看>>
APM终端用户体验监控分析(下)
查看>>
React Native 0.20官方入门教程
查看>>
JSON for Modern C++ 3.6.0 发布
查看>>
好好讲一讲:到底什么是Java架构师(含福利放送,名额有限)
查看>>
网络爬虫随记:2018-03-12启(refreshing)
查看>>
Tomcat9.0部署iot.war(环境mysql8.0,centos7.2)
查看>>
Hanlp自然语言处理中的词典格式说明
查看>>
ASP.NETMVC Model验证(五)
查看>>
网络工程重要知识点
查看>>
如此IT,真是挨踢
查看>>
网络安全之iptables 实验篇一
查看>>
Spring3.0核心组件的源码简单分析
查看>>