首页 > 数据库 >Redis 6 学习笔记 3 —— 用SpringBoot整合Redis的踩坑,了解事务、乐观锁、悲观锁

Redis 6 学习笔记 3 —— 用SpringBoot整合Redis的踩坑,了解事务、乐观锁、悲观锁

时间:2023-01-14 19:55:55浏览次数:58  
标签:事务 SpringBoot Redis om 笔记 命令 new 执行

SpringBoot整合Redis时踩到的坑

jdk1.8环境,用idea的Spring Initializr创建spring boot项目,版本我选的2.7.6。pom文件添加的依赖如下,仅供参考。

注意commons-pool2选错版本的话可能会报错,具体意思好像是说有什么Factory跟它的版本不匹配。

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

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

 

对应的配置文件代码如下(这个基本上是写死的)

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 这个函数已经是duplicated,用下面这个
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

 

用RDM,以及Java去连接子系统的redis报错:

Connection: WSLUbuntu > connected
Connection: WSLUbuntu > [runCommand] AUTH *******
Connection: WSLUbuntu > [runCommand] PING
Connection: Connection error on AUTH: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

上一个笔记是改密码解决了问题,没想到今天又出现一样的错误。总之它让我去看Redis log,就先看看。

 看起来是权限不够的问题,

joey@JoeyRedfield615:~$ sudo chmod 777 /var/lib/redis/rdb

 

这样就解决了。网上有很多各种各样的解决方案(Redis踩坑——MISCONF Redis is configured to save RDB snapshots),但是最好还是要根据生成的日志去判断要干什么。

事务、锁机制、乐观锁,做秒杀案例

Redis的事务操作和MySQL是不太一样的。

Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队。

Redis事务三特性

  • 单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 没有隔离级别的概念:队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行
  • 不保证原子性:事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

Transaction(事务) — Redis 命令参考 (redisfans.com)

Muiti、Exec、discard

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。组队的过程中可以通过discard来放弃组队。

 

 

 

如果执行阶段某个命令报出了错误(比如说给字符串值执行incr),则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚

不过如果有命令是语法错误(类似Java出现Error的情况),则整个队列的命令都不会被执行。

事务冲突的问题

直接点就是网购时的问题,如果有多个请求想要扣钱,那系统可不能出现让用户扣钱扣到负数的情况。。

由此就引出了乐观锁悲观锁的解决方案。

乐观锁

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

悲观锁

 

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block(阻塞)直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。(有一种MySQL事务等级设置成串行化的美)

Watch/Unwatch

WATCH key [key ...]

这个是可以实现乐观锁的命令。它可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

 

 

 由第9步可以看到结果为(nil),因为在⑨执行之前,debt已经被改过了。

标签:事务,SpringBoot,Redis,om,笔记,命令,new,执行
From: https://www.cnblogs.com/joey-redfield/p/17050196.html

相关文章

  • vue-cli笔记
    一、安装全局安装npminstall-g@vue/cli创建项目vuecreate项目名二、目录介绍src--main.js入口文件main.js介绍//引入vueimportVuefrom'vue'/......
  • 《态度-吴军》 读书笔记
    教育首先是关怀备至地、深思熟虑地、小心翼翼地去触及年轻的心灵。——苏霍姆林斯基一、前言《态度》一书为吴军老师给上高中和大学的两个女儿写的四十封家书,针对成长过......
  • linux工具grep的使用心得笔记
    grep作为linux管理中常用的三大工具之一(grep、awk、sed),其功能十分强大,因此难以对其进行全面的使用介绍,因此本文只作为个人学习的笔记之用。 grep的用处:在文本中匹配要......
  • springboot @Autowried报错
     原因:没啥,就是idea偶尔有薄毛病 解决:作用是屏蔽一些无关紧要的警告。使开发者能看到一些他们真正关心的警告。从而提高开发者的效率@SuppressWarnings("all")......
  • SpringBoot——核心原理入门
    SpringBoot概述BuildAnythingwithSpringBoot:**SpringBootisthestartingpointforbuildingallSpring-basedapplications.SpringBootisdesignedtoget......
  • SpringBoot——初始化器解析
    初始化器Spring是一个扩展性很强的容器框架,为开发者提供了丰富的扩展入口,其中一个扩展点便是ApplicationContextInitializer(应用上下文初始化器)。 ApplicationConte......
  • SpringBoot——监听器解析
    监听器模式监听器模式有要素事件监听器广播器触发机制系统监听器监听器ApplicationListener@FunctionalInterfacepublicinterfaceApplicationListener<Eext......
  • 数论学习笔记
    逆元定义存在$a\timesx\equiv1\pmod{m}$,我们称\(x\)为\(a\)的逆元。完全剩余系假设\(1\toP-1\)都存在逆元,我们则称他为一个完全剩余系。当......
  • Spring 学习笔记
    Spring笔记1.Spring基本概念这里介绍一下,spring的基本概念,简单的说一下ioc是什么,ioc容器是什么,ioc怎么实现的。spring默认是单例的1.1IOCioc是一种思想叫控制反转......
  • MySql学习笔记--进阶05
          ......