Redis事务
- 事务Redis 事务本质: 一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程的中,会按照顺序执行!一次性、顺序性、排他性、执行一些列的命令!
Redis事务没有没有隔离级别的概念!- 所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!
Redis单条命令式保存原子性的,但是事务不保证原子性!- redis的事务:
- 开启事务(multi)
- 命令入队(…)
- 执行事务(exec)
- 取消事务 (DISCARD)
- 事务队列中命令都不会被执行!
- 编译型异常(代码有问题!命令有错!),事务中所有的命令都不会被执行!
- 运行时异常(1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!
监控 Watch
- 悲观锁: 认为什么时候都会出问题,无论做什么都会加锁。
- 乐观锁: 认为什么时候都不会出问题,所以不会上锁,redis可以当乐观锁操作,就是使用watch来监控
- 更新数据的时候去判断一下,在此期间是否有人修改过这个数据。
- 获取
version - 更新的时候比较
versionRedis测监视测试正常执行成功!
Jedis
Redis官方推荐的java连接开发工具!使用Java操作Redis中间件!- 所有的命令都和jedis中的方法是一模一样的
整合SpringBoot
-
SpringBoot操作数据的有:spring-data jpa jdbc mongodb redis! -
说明:
在 SpringBoot2.x之后,原来使用的jedis被替换为了lettuce -
jedis: 底层采用的直连,如果多个线程操作的话是不安全的,如果想要避免不安全的,使用jedis pool连接池,这就更像 BIO 模式。 -
lettuce: 采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像 NIO 模式 -
源码分析
- RedisAutoConfiguration.java如下主要代码如下所示
@Bean
// 我们可以自己定义一个redisTemplate来替换这个默认的!
@ConditionalOnMissingBean(name = {"redisTemplate"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
// 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 <String, Object>
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
// 由于 String 是redis中最常使用的类型,所以说单独提出来了一个bean!
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
SpringBoot整合Redis
- 导入依赖
<!-- 操作redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 在
application.properites中配置连接
# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
- 测试
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("mikey","daq");
System.out.println(redisTemplate.opsForValue().get("mikey"));
}
}
- 序列化分析


- 关于对象的保存:所有的对象,都需要序列化
编写模板RedisTemplate
- 自己定义了一个
RedisTemplate - 这是一个固定模板,可以直接用
package com.daq.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 为了开发方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template=new RedisTemplate<String,Object>();
template.setConnectionFactory(factory);
// Json序列化配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om=new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// String 的序列化
StringRedisSerializer stringRedisSerializer=new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}

被折叠的 条评论
为什么被折叠?



