zoukankan      html  css  js  c++  java
  • redis分布式锁工具类


    (1)需要导入的包

    <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.0</version>
    </dependency>
    

    (2)JedisUtil类

    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    import java.util.Collections;
    
    /**
     * 不采用springTemplate 的操作类
     * 因为springTemplate 的SetNx 非原子性,可能导致锁永久锁住,释放失败
     */
    @Component("jedisUtil")
    public class JedisUtil {
    
    	private static final String LOCK_SUCCESS = "OK";
    	private static final String SET_IF_NOT_EXIST = "NX";
    	private static final String SET_WITH_EXPIRE_TIME = "PX";
    	private static final Long RELEASE_SUCCESS = 1L;
    
    	@Autowired
    	private JedisPool jedisPool;
    
    	/**
    	 * 尝试获取分布式锁
    	 * @param lockKey 锁
    	 * @param requestId 请求标识
    	 * @param expireTime 超期时间
    	 * @return 是否获取成功
    	 */
    	public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
    		Jedis jedis = null;
    		try{
    			jedis = jedisPool.getResource();
    			String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
    			if (LOCK_SUCCESS.equals(result)) {
    				return true;
    			}
    		} finally {
    			//归还 jedis 连接
    			if(jedis != null){
    				jedis.close();
    			}
    		}
    		return false;
    	}
    
    	/**
    	 * 释放分布式锁
    	 * @param lockKey 锁
    	 * @param requestId 请求标识
    	 * @return 是否释放成功
    	 */
    	public boolean releaseDistributedLock(String lockKey, String requestId) {
    		Jedis jedis = null;
    		try {
    			jedis = jedisPool.getResource();
    			String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    			Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
    			if (RELEASE_SUCCESS.equals(result)) {
    				return true;
    			}
    		} finally {
    			//归还 jedis 连接
    			if(jedis != null){
    				jedis.close();
    			}
    		}
    		return false;
    	}
    
    	/**
    	 * 设置值并设置超时时间
    	 * @param key
    	 * @param value
    	 * @param expireTime
    	 * @return
    	 */
    	public Long rpushString(String key, String value, int expireTime){
    		Jedis jedis = null;
    		Long result = 0L;
    		try {
    			jedis = jedisPool.getResource();
    			result = jedis.rpush(key, value);
    			if(result > 0){
    				jedis.expire(key,expireTime);
    			}
    		} finally {
    			if(jedis != null){
    				jedis.close();
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 批量插入
    	 * @param key
    	 * @param values
    	 * @param expireTime
    	 * @return
    	 */
    	public Long batchRpushString(String key, String[] values, int expireTime){
    		Jedis jedis = null;
    		Long result = 0L;
    		try {
    			jedis = jedisPool.getResource();
    			result = jedis.rpush(key, values);
    			if(result > 0){
    				jedis.expire(key,expireTime);
    			}
    		} finally {
    			if(jedis != null){
    				jedis.close();
    			}
    		}
    		return result;
    
    	}
    
    	/**
    	 * 释放锁
    	 * @param lockKey
    	 */
    	public Long releaseLock(String lockKey){
    		Long result = 0L;
    		Jedis jedis = null;
    		try {
    			jedis = jedisPool.getResource();
    			result = jedis.del(lockKey);
    		} finally {
    			if(jedis != null){
    				jedis.close();
    			}
    		}
    		return result;
    	}
    
    }
    
    

    (3)jedisPool配置

    可以根据自己情况换成pringboot类配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="3000"></property>
            <property name="maxIdle" value="300"></property>
            <property name="minIdle" value="10"></property>
            <property name="maxWaitMillis" value="15000"></property>
            <property name="minEvictableIdleTimeMillis" value="300000"></property>
            <property name="numTestsPerEvictionRun" value="3"></property>
            <property name="timeBetweenEvictionRunsMillis" value="60000"></property>
            <property name="testOnBorrow" value="true"></property>
            <property name="testOnReturn" value="true"></property>
            <property name="testWhileIdle" value="true"></property>
        </bean>
    
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">
            <!-- config -->
            <constructor-arg ref="jedisPoolConfig"/>
            <!-- host -->
            <constructor-arg value="127.0.0.1" type="java.lang.String" />
            <!-- port -->
            <constructor-arg value="6379" type="int" />
            <!-- timeout -->
            <constructor-arg value="15000" />
        </bean>
        <context:component-scan base-package="com.td.yousan.util"/>
    </beans>
    

    (4)使用举例

    @Resource
    private JedisUtil jedisUtil;
    
    
    String lockKey=userId;//锁key
    String requestId = UUID.randomUUID().toString();//请求标识
    final int EXPIRED_TIME = 300*1000;//redis 数据存储过期时间
    
    //加锁举例
    boolean lockResult = jedisUtil.tryGetDistributedLock(lockKey, requestId, EXPIRED_TIME)
    
    //放锁举例
    booleanr releaseResult =jedisUtil.releaseDistributedLock(lockKey, requestId);
    
    
  • 相关阅读:
    基于python批量获取Url
    记一次tp5.0.11rce
    centOS 6.2 x64系统上安装 oracle 11g R2 x64
    用xmanager连接Linux的配置步骤
    0级备份和全备
    配置EM遇到的问题
    转:如何迁移oracle 队列表
    oracle audit
    VIEWS for Oracle object privileges
    Oracle 脚本
  • 原文地址:https://www.cnblogs.com/ranandrun/p/JedisUtil.html
Copyright © 2011-2022 走看看