• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RedisTemplate实现分布式锁

武飞扬头像
Shadow_T
帮助3

RedisTemplate是Spring Data Redis提供的一个用于操作Redis数据库的模板类。它封装了Redis的操作,提供了一系列的方法,可以方便地进行Redis操作。

RedisTemplate提供了一系列的方法,包括字符串、列表、哈希、集合、有序集合等类型的操作方法。此外,它还提供了针对事务、流水线、分布式锁等高级操作的支持。

以下是通过RedisTemplate实现分布式锁的一个示例:

public class RedisLockUtils {
	private static volatile RedisTemplate<String, Object> redisTemplate;
	
	// 获取RedisTemplate实例
	private static RedisTemplate<String, Object> getRedisTemplate() {
		if (redisTemplate == null) {
			synchronized (RedisLockUtils.class) {
				if (redisTemplate == null) {
					redisTemplate = SpringBeanUtil.getBean("redisTemplate", RedisTemplate.class);
				}
			}
		}
		return redisTemplate;
	}
	
	/**
	* lockKey 锁 key
	* value 身份标识(保证锁不会被其他人释放)
	* expireTime 锁的有效时间
	**/
	public static Boolean lock(String lockKey, String value, long expireTime) {
		try {
			return getRedisTemplate().opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.SECONDS);
		} catch (Exception e) {
			throw new AppException("redis连接异常");
		]
	}	
	
	/**
	* key 锁的key
	* value 身份标识
	* return 成功返回true 失败返回false
	**/
	public static Boolean unlock2(String key, String value) {
		// 获取当前锁的拥有者
		Object currentValue = getRedisTemplate().opsForValue().get(key);
		Boolean result = false;
		// 判断value是否为锁的拥有者
		if (StringUtils.isNotEmpty(String.valueOf(currentValue)) && Objects.equals(currentValues, value)) {
			//删除锁
			result = getRedisTemplate.opsForValue().getOperations().delete(key);
		}
	}
}
学新通

在上面的代码中,lock()方法用于获取分布式锁,unlock2()方法用于释放分布式锁。

lock()方法首先使用setIfAbsent()方法尝试设置一个键值对,如果设置成功则说明获取锁成功;否则说明该锁已经被其他客户端持有,获取锁失败。并且通过expireTime设置锁的过期时间,以免产生死锁。

unlock2()方法首先获取锁的当前值,然后判断当前值是否等于请求者的身份标识,如果相等则说明当前客户端持有该锁,可以删除该锁,否则删除失败。

public void test() {
	RedisLockUtils.lock("test", "test", 60);
	// 执行业务操作
	...
	// 代码的最后释放锁
	RedisLockUtils.unlock2("test", "test");
}
@Component
public class SpringBeanUtil implements ApplicationContextAware {
	public SpringBeanUtils() {
	}
	
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		SpringBeanUtil.applicationContext = applicationContext;
	}
	
	// 用于静态的获取spring容器中的bean
	public static <T> T getBean(Class<T> requiredType) {
		return applicationContext.getBean(requiredType);
	}


}
学新通

Redis连接信息配置在application.properties中:

spring.redis.host=your_redis_host
spring.redis.port=your_redis_port
spring.redis.password=your_redis_password
spring.redis.database=your_redis_database

依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

注:
若application.properties中的redis连接信息需要用密文保存,则需要将getRedisTemplate()方法改为以下内容:

		if (redisTemplate == null) {
			synchronized (RedisLockUtils.class) {
				if (redisTemplate == null) {
					redisTemplate = SpringBeanUtil.getBean("redisTemplate", RedisTemplate.class);
					RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
					config.setHostName("redis地址");
					config.setPort("redis端口");
					config.setPassword("解密后的redis密码");
					LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config);
					connectionFactory.afterPropertiesSet();
					redisTemplate.setConnectionFactory(connectionFactory);
				}
			}
		}
		return redisTemplate;

在上述代码中,我们首先创建一个RedisStandaloneConfiguration对象,设置Redis服务器的主机名、端口和密码等参数,然后使用此对象创建LettuceConnectionFactory连接工厂。最后,将此连接工厂设置为RedisTemplate的连接工厂。
另外,如果您的应用程序需要连接到多个Redis服务器,则可以使用RedisClusterConfiguration或RedisSentinelConfiguration对象代替RedisStandaloneConfiguration对象。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhigaj
系列文章
更多 icon
同类精品
更多 icon
继续加载