SpringBoot学习示例—整合Redis之StringRedisTemplate、乐观锁、事务(附完整项目代码)


作者:空白

1. 前言

这篇文章你能学到,SpringBoot整合Redis的最简单方式,不需要任何复杂的配置。还有完整的乐观锁,分布式锁,事务等实现样例代码供你选择。

2. 整合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服务了,只需这样简单的两个配置。

3. StringRedisTemplate基本操作及测试

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

4. 实现Redis事务

事务的实现需要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事务测试成功。

5. 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"获取。

alt

扫码或搜索:前沿科技
发送 290992
即可立即永久解锁本站全部文章