场景:需要存两条数据到redis中,并且两条要么都存要么都不存,需要事务来控制

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

  redisOperations.multi();
  redisOperations.opsForHash().put("xxx", field, hashValue);
  redisOperations.opsForSet().add(key,setvalue);
  redisOperations.exec();

但是执行之后发现redis中并没有存入想要的数据,而且抛出异常  No ongoing transaction. Did you forget to call multi?

原因:发现上面代码中mutil()方法和exec()方法都会从新建立新的连接,导致数据丢失

解决方法:采用RedisTemplate的SesionCallback实现在同一个Connection中,完成多个操作的方法:

  SessionCallback sessionCallback = new SessionCallback() {
    @Override
    public Object execute(RedisOperations redisOperations) throws DataAccessException {
      redisOperations.multi();
      redisOperations.opsForHash().put("xxx", field, hashValue);
      redisOperations.opsForSet().add(key,setvalue);
      return redisOperations.exec();
    }
  };
  redisTemplate.execute(sessionCallback);

注意:匿名内部类中要使用外部类的局部变量,局部变量需要使用final来修饰。

原因:局部变量的生命周期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命周期与其它类一样:自创建一个匿名内部类对象,系统为该对象分配内存,直到没有引用变量指向分配给该对象的内存,它才会死亡(被JVM垃圾回收)。所以完全可能出现的一种情况是:成员方法已调用结束,局部变量已死亡,但匿名内部类的对象仍然活着。所以如果内部类对象访问了同一个方法的局部变量就要求该局部变量的生命周期不能小于匿名类的生命周期,所以需要将被匿名内部类使用到的局部变量使用final修饰。定义为final后,编译程序的实现方法:对于匿名内部类对象要访问的所有final类型局部变量,都拷贝成为该对象中的一个数据成员。这样,即使栈中局部变量已死亡,但被定义为final类型的局部变量的值永远不变,因而匿名内部类对象在局部变量死亡后,照样可以访问final类型的局部变量,因为它自己拷贝了一份,且与原局部变量的值始终一致。

redis参考:https://blog.csdn.net/congcong68/article/details/52734735

匿名内部类参考:https://blog.csdn.net/qq_27840621/article/details/60958276

redis事务报错No ongoing transaction. Did you forget to call multi?的更多相关文章

  1. No ongoing transaction. Did you forget to call multi?

    2016-10-21 14:41:47,551 [ERROR] [http-nio-8032-exec-2] TransactionSynchronizationUtils:171 - Transac ...

  2. REDIS持久化报错失败

    redis log报错: [7666] 15 Jan 00:22:36.028 # Error moving temp DB file on the final destination: Invali ...

  3. SpringBoot- springboot集成Redis出现报错:No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory'

    Springboot将accessToke写入Redisk 缓存,springboot集成Redis出现报错 No qualifying bean of type 'org.springframewo ...

  4. redis编译报错总结

    redis编译报错总结: 1.不能编译没有GCC 编译工具安装报错:问题1:make时可能会报如下错误cc -c -std=c99 -pedantic -O2 -Wall -W   -g -rdyna ...

  5. redis启动报错:Fatal error loading the DB: Invalid argument

    redis启动报错 add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be ...

  6. .Net Core redis 调用报错 '6000 Redis requests per hour' 解决 6000 此调用限制

    问题描述 redis 是一种基于内存,性能高效的 NoSQL 数据库,性能高主要就体现在数据交互耗时较短,能够段时快速的对用户的请求做出反应,所以在业务比较复杂或交互量需求大时,必然会超过 6000次 ...

  7. 记一次实际开发过程中遇到事务报错问题 Transaction synchronization is not active

    一:问题场景 在一次http请求的后台接口中返回结果中出现了这个错误信息“Transaction synchronization is not active”,意思是“事务同步器没有激活”,但是被调用 ...

  8. Ubuntu 14.04下Redis安装报错:“You need tcl 8.5 or newer in order to run the Redis test”问题解决

    Redis简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工 ...

  9. 非root用户启动redis容器报错mkdir: cannot create directory '/bitnami/redis': Permission denied

    问题:使用docker启动容器时,报错如下 zh@debian:~/testPath$ docker-compose up redis Starting testpath_redis_1 ... do ...

随机推荐

  1. 最常用的15大Eclipse开发快捷键技巧

    1.alt+?或alt+/:自动补全代码或者提示代码 这个是我最得意的快捷键组合了,尤其是当输入syso几个字符之后,2个手指轻松按下这2个键的时候,自动就补全System.out.println() ...

  2. 话谈C#第二天

    今天做了几个小小的练习,和大家分享一下. 1.用*打印出等腰三角形,代码如下: static void Main(string[] args) { int n = 5; for (int i = 1; ...

  3. 【GDOI2018模拟8】 数学竞赛 三角函数性质+记忆化搜索

    数据范围:p,q≤20. 只能说我整个人傻逼了..... 我们考虑三角函数的部分性质: $sin(x)=\sqrt{ 1-cos^2(x)}$ $cos(x)=\sqrt{1-sin^2(x)}$ $ ...

  4. javascript数据结构与算法--二叉树遍历(后序)

    javascript数据结构与算法--二叉树遍历(后序) 后序遍历先访问叶子节点,从左子树到右子树,再到根节点. /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * * * */ ...

  5. JavaScript 闭包解决计数器问题

    JavaScript 闭包解决计数器问题 var add = (function () { var counter = 0; return function () {return counter += ...

  6. AbstractFactory抽象工厂模式(创建型模式)

    1.new 的问题 常见的对象创建方法: //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对具体实例的变化 怎么理解上面这句话呢? 可以这样理解:我 ...

  7. Vue的实时时间转换Demo

    Vue的实时时间转换Demo time.html: <!DOCTYPE html> <html lang="en"> <head> <me ...

  8. 6.6. Access Control

    解读 6.6.2.2. Qualified Access to a protected Constructor https://docs.oracle.com/javase/specs/jls/se7 ...

  9. Android硬件抽象层(HAL)深入剖析(一)【转】

    作为一个搞android驱动或者说搞底层的人,我觉得对于hal那是必须要掌握的,而且必须达到一定深度,于是我总结了一下,将整个自己的分析思路写下来. 主要是看android源代码,根据源代码得到的思路 ...

  10. php通过生成动态变量(变量名中还有变量)

    借鉴:http://blog.sina.com.cn/s/blog_7193eeac0100zwld.html 如果想for循环生成变量 如: $a1,$a2,$a3.... $name = &quo ...