<!--版本号和spring parent版本号一致-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
package com.itllc.config.RedisConfig;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class RedissonConfig {
@Value("${spring.redis.host}")
String REDIS_HOST;
@Value("${spring.redis.port}")
String REDIS_PORT;
@Value("${spring.redis.password}")
String REDIS_PASSWORD;
@Value("${spring.redis.database}")
int REDIS_DATABASE;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig r = config.useSingleServer();
r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
.setDatabase(REDIS_DATABASE)
.setConnectionMinimumIdleSize(5)
.setConnectionPoolSize(10);
if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
r.setPassword(REDIS_PASSWORD);
}
return Redisson.create(config);
}
}
package com.itllc.config.RedisConfig;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class RedissonConfig {
@Value("${spring.redis.host}")
String REDIS_HOST;
@Value("${spring.redis.port}")
String REDIS_PORT;
@Value("${spring.redis.password}")
String REDIS_PASSWORD;
@Value("${spring.redis.database}")
int REDIS_DATABASE;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig r = config.useSingleServer();
r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
.setDatabase(REDIS_DATABASE)
.setConnectionMinimumIdleSize(5)
.setConnectionPoolSize(10);
if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
r.setPassword(REDIS_PASSWORD);
}
return Redisson.create(config);
}
}
package com.itllc.aop;
import lombok.Getter;
import lombok.Setter;
import org.redisson.api.RLock;
/**
* @description 加锁结果类封装了加锁状态和RLock。
*
* @author lilinchun
* @date 2023/06/28
*/
@Setter
@Getter
public class LockResult {
private LockResultStatus lockResultStatus;
private RLock rLock;
}
package com.itllc.aop;
/**
* @description 加锁结果状态枚举类
*
* @author lilinchun
* @date 2023/06/28
*/
public enum LockResultStatus {
/**
* 通信正常,并且加锁成功
*/
SUCCESS,
/**
* 通信正常,但获取锁失败
*/
FAILURE,
/**
* 通信异常和内部异常,锁状态未知
*/
EXCEPTION;
}
@GetMapping(value = "/redisLock")
@ApiOperation("使用redis锁")
public Result<Boolean> useRedis(@NotBlank @ApiParam(value = "用户信息", required = true) @RequestParam("userId") String userId) {
return new Result<>(redisService.useRedis(userId));
}
// ——————————————————————————————————————————————————————
@Resource
private LockManager lockManager;
public Boolean useRedis(String userId) {
// 锁:userId, 锁超时时间:5s, 锁等待时间:50ms
LockResult lockResult = lockManager.lock(userId, 5000, 1000);
try {
// 业务代码
System.out.println("执行业务2s!!!!!");
Thread.sleep(2000);
System.out.println("执行业务完成!!!!!");
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
lockManager.unlock(lockResult.getRLock());
}
return true;
}
并发请求不同的参数
总结:两次测试结果说明redis的锁生效了,并且有效的解决了分布式事务的问题
注意:
解锁方式
if(lock.isLocked() && lock.isHeldByCurrentThread()){
lock.unlock();//解锁
}
不然会出现问题,自己加的锁自己解锁,还需要判断加锁是否成功了
问题文章:https://blog.csdn.net/xiyang_1990/article/details/119876496