场景:需要存两条数据到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. absolute

    在需要用到小图标时,可以使用position:absolute,它具有消除float和位置不变特性.使用absolute可以浮现在同级元素的上方.用margin进行精确定位即可,也不必使用top,le ...

  2. 下载一个vue项目执行npm install 后运行项目npm run dev后出错 - 问题解决

    在SVN上拉下来一个vue项目,上面没有提交项目里面的node_modules文件夹,所以要自己执行 npm install 安装,但安装完后运行项目后却报错了: $ npm run dev > ...

  3. git命令上传项目到码云总结

    码云上传项目git命令总结: git clone https://git.oschina.net/xh-lxx/xh-lxx.oschina.io.git 进入到克隆下来的文件夹,然后操作git命令 ...

  4. selenium IDE的基本命令

    waitForText.verifyText和asserText命令 waitForText语句在测试执行时用来判断某些文本是否存在界面中.若界面上显示了指定文本,测试程序会继续执行:若等待一段时间后 ...

  5. word转html 压缩图片网站

    word转html https://docs.google.com/document/d/1MS-os1NcEPSEe2OWRenGR_6CsEmEQUchoQoh-abmL1Y/edit 压缩图片 ...

  6. python中的sort方法

    Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不 ...

  7. postman—Runner的使用

    1.首先在postman新建要批量运行的接口文件夹,新建一个接口,并设置好全局变量. 2.然后在Test里面设置好要断言的方法 如: pm.test("Status code is 200& ...

  8. unity 图片 粉碎效果 破碎效果

    效果: 点击按钮后: 这些碎片具有物理碰撞效果,下面会有隐形的支柱垫着碎片,n秒后支柱消失,碎片落下 当然你也可以控制生成的碎片,让他们从下而上一块一块地落下 插件源码: https://github ...

  9. MySQL 忘记密码怎么办?

    有时候经常忘记密码,或者更改密码时按错键的,或者不知名的错误.下面介绍windows下,解决办法都是差不多: 更改登录权限为全开放,进入后再更改权限更改密码 有几种情况 (1)如果是使用 WampSe ...

  10. Extjs相关知识点梳理

      store是一个为Ext器件提供record对象的存储容器,行为和属性都很象数据表 方法:不列举继承来的方法 Store( Object config ) 构造,config定义为{ autoLo ...