stringRedisTemplate.opsForValue().increment("count", 1);
而我们的生产环境重启服务后,开启的 Redis 事务支持又被重置为默认值了 , 所以后续的 Redis 递增操作都能正常执行 。
四、修复方案目前想到了两种解决方案:
- 方案一:每次 Redis 的事务操作完成后,关闭 Redis 事务支持,然后再执行 @Transactional 中的 Redis 命令 。(有弊端)
- 方案二:创建两个 StringRedisTemplate , 一个专门用来执行 Redis 事务,一个用来执行普通的 Redis 命令 。
文章插图
但是这种写法有个弊端,如果在执行 Redis 事务期间,在 @Transactional 注解的方法里面执行 Redis 命令,则还是会造成返回结果为 null 。
文章插图
4.2 方案二弄两个 RedisTemplate Bean,一个是用来执行 Redis 事务的 , 一个是用来执行普通 Redis 命令的(不支持事务) 。不同的地方引入不同的 Bean 就可以了 。
先创建一个 RedisConfig 文件,自动装配两个 Bean 。一个 Bean 名为
stringRedisTemplate
代表不支持事务的,执行命令后立即返回实际的执行结果 。另外一个 Bean 名为 stringRedisTemplateTransaction
,代表开启 Redis 事务支持的 。代码如下所示:
文章插图
接下来在测试的 Service 类中注入两个不同的 StringRedisTemplate 实例,代码如下所示:
文章插图
Redis 事务的操作改写成这样,且不需要手动开启 Redis 事务支持了 。用到的 StringRedisTemplate 是支持事务的那个实例 。
文章插图
在 Spring 的 @Tranactional 中执行的 Redis 命令如下所示,用到的 StringRedisTemplate 是不支持事务的那个实例 。
文章插图
然后还是按照上面场景 3 的测试步骤,先执行 testRedisMutil 方法,再执行 testTransactionAnnotations 方法 。
验证结果:Redis 递增操作正常返回 count 的值,修复完成 。
另外关于 Redis 事务使用还有一个坑 , 就是 Redis 连接未释放,导致获取不到连接了,这是下一个话题了~
参考资料:https://blog.csdn.net/qq_34021712/article/details/79606551
- END -
关于我8 年互联网开发经验 , 擅长微服务、分布式、架构设计 。目前在一家大型上市公司从事基础架构和性能优化工作 。
InfoQ 签约作者、蓝桥签约作者、阿里云专家博主、51CTO 红人 。
推荐阅读
- 一 Redis数据结构-Redis的数据存储及String类型的实现
- Redis Cluster 原理说的头头是道,这些配置不懂就是纸上谈兵
- 抛砖系列之redis监控命令
- SpringCloud整合分布式事务Seata 1.4.1 支持微服务全局异常拦截
- 记一次 .NET 某娱乐聊天流平台 CPU 爆高分析
- Redis 01: 非关系型数据库 + 配置Redis
- Redis 02: redis基础知识 + 5种数据结构 + 基础操作命令
- 1 Redis—问题
- 之四 2流高手速成记:SpringBoot整合redis及mongodb
- 记录一次成功反混淆脱壳及抓包激活app全过程