一、问题描述

Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,Redis对事物支持不会很复杂,当一个客服端连接Redis服务时,发出了MULTI命令时,这个连接会进入事物,在执行MULTI命令之后,执行所有的命令都不会执行,会先放到一个队列中,会提示正在Query,当最后执行EXEC命令之后,Redis会按照之前的进入队列的顺序,执行命令。

Spring Data Redis 是对JRedis的客服端进行很好的封装, spring Data Redis的RedisTemplate提供了MULTI、EXEC命令进行封装,但RedisTemplate先执行调用MULTI方法,然后在执行其它的命令,最后执行EXEC方法时,会出现报错:Caused by:Redis.clents.jedis.exceptions.JedisDataException:ERR EXEC without MULTI问题。

二、原因分析

Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,我们需要重新添加数据,对原先的数据进行删除,在多个线程情况下数据会丢失,所以我们需要事务完成相应的效果。

Spring Data Redis的RedisTemplate提供了MULTI、EXEC命令进行封装,远看可以解决问题时,代码实现:

  1. stringRedisTemplate.multi();
  2. stringRedisTemplate.delete("test");
  3. stringRedisTemplate.opsForValue().set("test","2");
  4. stringRedisTemplate.exec();

结果保 错误:

我们查询multi、delete等源代码,发现会执行RedisTemplate类中execute()方法进行跟踪发现 RedisCallback中doInRedis获取的RedisConnection每次都是新的,所以才导致该问题。

分析Redis源代码:

我们查看multi实现

                                
                    跟踪发现RedisConnection conn每次都是新的,导致出现那个错误

三、解决方案

只能自己实现RedisCallBack底层,采用RedisTemplate的SesionCallback来完成在同一个Connection中,完成多个操作的方法:

  1. SessionCallback<Object>   sessionCallback=new SessionCallback<Object>(){
  2. @Override
  3. public Object execute(RedisOperations operations) throws DataAccessException{
  4. operations.multi();
  5. operations.delete("test");
  6. operations.opsForValue.set("test","2");
  7. Object val=operations.exec();
  8. return val;
  9. }
  10. }
  11. StringRedisTemplate.execute(sessionCallback);

RedisTemplate实现事物问题剖析和解决的更多相关文章

  1. C#里面的事物回滚,解决同步数据插入时出现重复数据

    什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...

  2. 剖析和解决Python中网络粘包的正确姿势

    目录 1.粘包及其成因 1.1.粘包产生 1.2.粘包产生的原因 2.尝试解决粘包 2.1.指定数据包的长度 2.2.固定数据包的长度 2.3.用函数实现多次调用发送数据 3.解决粘包问题的正确姿势 ...

  3. Springboot与ActiveMQ、Solr、Redis中分布式事物的初步探索

    Springboot与ActiveMQ.Solr.Redis中分布式事物的初步探索 解决的场景:事物中的异步问题,当要求数据库与solr服务器的最终一致时. 程序条件: 利用消息队列,当数据库添加成功 ...

  4. Redis 事物、悲观、乐观锁 (详细)

    1,概论 事物这东西相信大家都不陌生吧,在学习Spring,Mybatis等框架中, 只要是涉及到数据存储和修改的,都会有事物的存在, 废话就不多说了下面我们来简单的介绍下Redis事物以及锁. 2, ...

  5. 集成Spring事物管理

    什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取.事物的正确执行使得数据库从一种状态转换为另一种状态. 事物必须服从ISO/IEC所制定的ACID原则.ACID ...

  6. Idea使用记录--添加Problems&&解决Autowired报错could not autowire

    今天在使用Idea的时候,发现Idea在整个每次找到错误代码非常不方便(Idea如果类中有错误,没有打开过类并不会提示,比如构建工程后缺少jar包问题).我想快速看到工程哪里出问题类似于eclipse ...

  7. CDN高级技术专家周哲:深度剖析短视频分发过程中的用户体验优化技术点

    深圳云栖大会已经圆满落幕,在3月29日飞天技术汇-弹性计算.网络和CDN专场中,阿里云CDN高级技术专家周哲为我们带来了<海量短视频极速分发>的主题分享,带领我们从视频内容采集.上传.存储 ...

  8. JDBC中的事物处理

    一项事物是由一个或是多个操作所组成的一个不可分割的工作单元.我们通过提交commit()或是回退rollback()来结束事务的操作. JDBC的事物处理包括三个方面:1:自动提交模式: 2:事务隔离 ...

  9. 浅谈,seata在使用feign-url通过域名调用时分布式事务不生效的问题及解决

    浅谈,seata在使用feign-url通过域名调用时分布式事务不生效的问题及解决 ​ 在前几个月时,我们项目出现了分布式事务的问题,那么什么是分布式事务问题呢,简单的说,我们有俩服务A和B,它们对应 ...

随机推荐

  1. 利用Java剖析工具JProfiler查找内存泄漏的方法

    本文主要介绍如何如何利用在使用JProfiler时意识到内存泄漏以及查找内存泄漏的几种方法. 工具/原料   JProfiler 方法/步骤   JProfiler的内存视图会话提供了内存使用情况的动 ...

  2. jquery实现仿京东侧边栏

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. Sql Server数据库自增长字段标识列的插入或更新修改操作办法

    写在前面的话:在日常的Sql server开发中,经常会用到Identity类型的标识列作为一个表结构的自增长编号.比如文章编号.记录编号等等.自增长的标识很大程度上方便了数据库程序的开发,但有时候这 ...

  4. Session 活化与钝化 与tomcat钝化驱动器

    1,绑定到Session中的 对象有多种状态,分别是   绑定   解除绑定     钝化    活化. 绑定 是保存,通过session.setattribute把对象保存到session的对象当中 ...

  5. iOS 获取沙盒文件路径及 写入/删除 沙盒文件

    出于安全考虑,iOS系统的沙盒机制规定每个应用都只能访问当前沙盒目录下面的文件(也有例外,比如系统通讯录能在用户授权的情况下被第三方应用访问),这个规则把iOS系统的封闭性展现的淋漓尽致. 一.沙盒中 ...

  6. iOS状态栏详解(隐藏)

    状态栏的隐藏 状态栏的隐藏主要有两种方法:方法一:通过代码控制 @interface UIApplication(UIApplicationDeprecated) // Setting statusB ...

  7. Gradle 庖丁解牛(构建生命周期核心托付对象创建源代码浅析)

    [工匠若水 http://blog.csdn.net/yanbober 未经同意严禁转载,请尊重作者劳动成果.私信联系我] 1 背景 上一篇<Gradle 庖丁解牛(构建源头源代码浅析)> ...

  8. 【Android实战】----从Retrofit源代码分析到Java网络编程以及HTTP权威指南想到的

    一.简单介绍 接上一篇[Android实战]----基于Retrofit实现多图片/文件.图文上传中曾说非常想搞明确为什么Retrofit那么屌. 近期也看了一些其源代码分析的文章以及亲自查看了源代码 ...

  9. hbase计数器

    1 计数器 计数器可以方便.快速地进行计数操作,而且避免了加锁等保证了原子性的操作.   1.1 Java API 操作 HBase 计数器 public Result increment(final ...

  10. 【WPF】CommandParameter解决多传参问题

    方法一:传参按钮控件自身绑定的ItemSource 用WAF框架实现MVVM,按钮的点击事件都要通过Command来传递到这个View对应的ViewModel上,再通过ViewModel传递到上层的C ...