这篇文章你能学到,SpringBoot整合Redis的最简单方式,不需要任何复杂的配置。还有完整的乐观锁,分布式锁,事务等实现样例代码供你选择。
SpringBoot项目引入redis依赖
<!-- 引入 redis 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </dependency>
redis配置
springboot项目默认使用StringRedisTemplate,StringRedisTemplate和RedisTemplate不同,前者比较简单,只需要配置redis参数就行。
第一种
在application.yml文件中配置下面的参数。
spring: redis: #redis数据库地址 host: localhost port: 6379 password: timeout: 1000 #redis数据库索引,默认0 database: 1
第二种
在application.properties文件中配置下面的参数。
# REDIS (RedisProperties) # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=localhost # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=5000
使用StringRedisTemplate
直接在service实现类中注入StringRedisTemplate。
@Autowired private StringRedisTemplate redisTemplate;
到这里,我们项目就能正常使用redis服务了,只需这样简单的两个配置。
Redis基本操作测试类RedisOperation
启动测试demo,RedisOperation类基本命令测试方法自动运行。RedisOperation实现了Spring接口ApplicationRunner,测试代码放在run方法中。读者可以查看demo项目。
测试set , get 操作 测试队列的 lpush , lpop , llen 等 操作 key stringRedisTemplate 的value为:stringRedisTemplate stringRedisTemplateList队列长度:9 测试过期设置 操作 设置stringRedisTemplate 过期时间3s 休眠两秒。。 检测key stringRedisTemplate 是否过期:-2( -2 代表 key过期已不存在) •The command returns -2 if the key does not exist. •The command returns -1 if the key exists but has no associated expire. 其他命令测试: resultSet:[22, 33, 44] resultSet1:[1, 2, 3] redisList----1 size----2 leftPop----4 rightPop----3 range----[] range1----[] remove----0
事务的实现需要Redis的3个命令:watch multi exec 。
redis命令
watch:用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
multi:用于标记一个事务块的开始。事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性(atomic)地执行。
exec:执行所有事务块内的命令。
代码实现
/* * 实现并测试Redis事务 */ public void testTransaction() { stringRedisTemplate.setEnableTransactionSupport(true); try { stringRedisTemplate.multi();//开启事务 stringRedisTemplate.opsForValue().increment("transaction", 1); if(true) throw new Exception(); stringRedisTemplate.opsForValue().increment("transaction2", 2); //提交 stringRedisTemplate.exec(); }catch (Exception e){ System.out.println("redis事务回滚了"); //开启回滚 stringRedisTemplate.discard(); } }
测试结果
transaction的value值没有变,还是1。
测试redis事务回滚############################################ 【执行前】事务key transaction:1 【执行前】事务key transaction2:1 redis事务回滚 【执行后】事务key transaction:1 【执行后】事务key transaction2:1 redis事务测试结果:transaction的value值没变 ,自增操作回滚了
分析:transaction的的increment操作并没有成功,说明redis事务测试成功。
Redis实现乐观锁,是基于Redis事务实现的。在这里,乐观锁思想体现在:谁先修改了key的值,谁就执行成功,后修改的事务会watch到key的变更而回滚事务,执行失败。从这个逻辑上看,就完全符合乐观锁的思想。
同时,运行在不同的客户端,这也是分布式锁,我们只需要将这段乐观锁逻辑做个升级改造:如果锁获取失败,则循环重复执行这段抢锁逻辑,直至获取成功或超时。这个升级的逻辑,读者可以自由发挥。
代码实现
/* * 实现乐观锁,乐观锁是依据redis事务实现的 */ public Object testRedisOptismLock(String value) { try { stringRedisTemplate.watch("OptismLock"); // 1 stringRedisTemplate.multi(); stringRedisTemplate.boundValueOps("OptismLock").set(value); TimeUnit.SECONDS.sleep(4); List<Object> list= stringRedisTemplate.exec(); System.out.println(list); if(list != null&&!list.isEmpty() ){ //操作成功 System.out.println(value+"值设置成功"); }else{ //操作失败 System.out.println(value+"值设置失败"); } } catch (Exception e) { e.printStackTrace(); } //自增 num.incrementAndGet(); return null; }
测试结果
测试代码可以查看demo项目的RedisOperation类
乐观锁测试############################################ 乐观锁测试中,再等待1s 乐观锁测试中,再等待1s 乐观锁测试中,再等待1s 乐观锁测试中,再等待1s 乐观锁测试中,再等待1s [] [true] task1值设置失败 [] task2值设置失败 task3值设置成功 乐观锁测试过后key的结果:task3
完整的demo项目,请关注公众号“前沿科技bot“并发送"StringRedisTemplate"获取。