Redis 6 学习笔记 3 —— 用SpringBoot整合Redis的踩坑,了解事务、乐观锁、悲观锁
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已经被改过了。
Redis 6 学习笔记 3 —— 用SpringBoot整合Redis的踩坑,了解事务、乐观锁、悲观锁的更多相关文章
- Redis:学习笔记-02
Redis:学习笔记-02 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 4. 事物 Redis 事务本 ...
- SpringBoot系列十:SpringBoot整合Redis
声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ...
- Git学习笔记与IntelliJ IDEA整合
Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...
- SpringBoot整合Redis、ApachSolr和SpringSession
SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...
- SpringBoot整合Redis及Redis工具类撰写
SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...
- SpringBoot 整合 Redis缓存
在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ...
- springboot整合redis(注解形式)
springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...
- springboot整合redis(简单整理)
Redis安装与开启 我这里是在windows上练习,所以这里的安装是指在windows上的安装,操作非常简单,点击https://github.com/MicrosoftArchive/redis/ ...
- SpringBoot整合redis哨兵主从服务
前提环境: 主从配置 http://www.cnblogs.com/zwcry/p/9046207.html 哨兵配置 https://www.cnblogs.com/zwcry/p/9134721. ...
- springboot整合redis——redisTemplate的使用
一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...
随机推荐
- spring cloud zuul实践
一. 描述 Spring Cloud Zuul是基于Netflix开源的Zuul项目构建而成,它作为微服务架构中的网关服务,主要用于实现动态路由.负载均衡和请求过滤等功能. 动态路由:Zuul根据预设 ...
- 利用InnoStep在VS编译时自动构建安装包
摘要 很多同学在C/S开发领域或多或少都可能会遇到需要制作安装包的场景,打包的工具也是五花八门,例如有NSIS.InstallShield.Wix Toolset.ClickOnce等等,这里以Inn ...
- Burnside 定理
Burnside 定理 问题: 给定一个 \(n\) 个点,\(n\) 条边的环,有 \(m\) 种颜色,给每个顶点染色,问有多少种本质不同的染色方案,答案对 \(10^9+7\) 取模 注意本题的本 ...
- C++ 核心指南之 C++ 哲学/基本理念(下)
C++ 核心指南(C++ Core Guidelines)是由 Bjarne Stroustrup.Herb Sutter 等顶尖 C+ 专家创建的一份 C++ 指南.规则及最佳实践.旨在帮助大家正确 ...
- 安装 配置 正向 解析 DNS方法
安装 配置 正向 解析 DNS方法 1,安装dhcp [root@localhost ~]#yum install bind* -y 2,关闭防火墙和selinux [root@localhost ~ ...
- Excel中的RIGHT函数
问题:从数据库中导出35800个用户code(属于179家单位,每个单位200个用户),用户code共16位,前14位带有用户属性(如:角色.单位.部门等),后四位为每个单位用户的递增自然数.想要对全 ...
- [ABC148F] Playing Tag on Tree
2023-03-04 题目 题目传送门 翻译 翻译 难度&重要性(1~10):5 题目来源 AtCoder 题目算法 最短路 解题思路 考虑到 T 想活得久, A 想尽早追上 T ,所以我们就 ...
- Android源码-生成系统签名文件
一.生成keystore签名文件 android 源码目录build\target\product\security 取platform.pk8 platform.x509.pem放到一个目录下 生成 ...
- Azure Data Factory(六)数据集类型为Dataverse的Link测试
一,引言 之前有讲过 Azure Data Factory 的 Copy Data 的操作,演示了将 Blob Storage1 的数据通过 Azure Data Factory 复制到 Blob S ...
- 如何调用API接口获取淘宝商品数据
淘宝商品数据的获取是一项非常重要的技术,它可以为淘宝卖家和买家提供有利的数据分析和扩展市场的机会.调用API接口是一种快速.方便.高效的方式获取淘宝商品数据. 以下是一些步骤来调用API接口来获取淘宝 ...