Redis分布式锁用于高并发

1、在Spring中引入redisson和JedisPool两个对象

/**
 * 
 */
package com.banksteel.finance.pay.assembly.utils;

import org.redisson.Redisson;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;


/**
 * @description redis配置文件
 * @className RedisCacheConfiguration
 * @projectName banksteel-finance-pay-assembly-service-provider
 * @author fangsy
 * @createTime 2019年2月15日上午8:54:54
 * @version 1.0.0
 */
@Configuration
public class RedisCacheConfiguration extends CachingConfigurerSupport{
	
	private Logger logger = LoggerFactory.getLogger(RedisCacheConfiguration.class);

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;

    @Value("${spring.redis.password}")
    private String password;

    
    @Bean
    public JedisPool redisPoolFactory() {
        logger.info("JedisPool注入成功!!");
        logger.info("redis地址:" + host + ":" + port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setJmxEnabled(true);
        jedisPoolConfig.setBlockWhenExhausted(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout,password);
        
        return jedisPool;
    }
    
    @Bean
    public Redisson redisson() {
    	logger.info("开始初始化redisson");
		Config config = new Config(); 
		config.useSingleServer()
		        .setPassword(password)
		
				.setAddress("redis://"+host+":"+port)
				// 客户端连接数量
				.setConnectionPoolSize(100)
				// 连接超时时间
				.setConnectTimeout(timeout)
				// 命令失败重试次数
				.setRetryAttempts(10)
				// 空闲连接数超时
				.setIdleConnectionTimeout(timeout);

		return (Redisson) Redisson.create(config);
    }
    
   
}

2、工具类用于封装redis分布式锁工具类

/**
 * 
 */
package com.banksteel.util.redis;

import java.util.concurrent.TimeUnit;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description 分布式锁redisson工具类
 * @className RedissonUtils
 * @projectName banksteel-finance-system-assembly-service-provider
 * @author fangsy
 * @createTime 2019年2月11日下午2:37:13
 * @version 1.0.0
 */
public class RedisUtils {

	private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);
	
	public interface LockCallBack{
		String call()  ;
	}
	
	
	/**
	 * @description 尝试获取可重入锁(非公平)
	 * @projectName banksteel-finance-util
	 * @author fangsy
	 * @createTime 2019年2月12日下午7:49:35
	 * @version 1.0.0
	 * @param lockCallBack
	 * @param redisson
	 * @param lockKey 加锁的key值,根据业务逻辑中的key值控制锁
	 * @param waitTime 最多等待时间  单位秒 (根据加锁代码执行时间和并发量来设置)
	 * @param leaseTime 获取锁后超时释放锁时间   单位秒 (防止死锁,一般根据加锁代码执行时间来设置)
	 */
	public static String acquireLock(LockCallBack lockCallBack, Redisson redisson, String lockKey, int waitTime, int leaseTime)
	{  
		String message = "";
		RLock lock = null;
		boolean locked = false;
		try {
			lock = redisson.getLock(lockKey);  
			
			if (lock != null) {	
				locked = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS); 
			}
			
			if(locked){
				message = lockCallBack.call();
			}
		} catch (Exception e) {
			logger.error("尝试加锁失败", e);
		} finally {
			if (lock != null && locked){
				lock.unlock();
			}
		}
		
		return message;
    } 
	
	
	
	
	
}

3、在业务场景中的使用
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值