RedisTemplate实现事物问题剖析和解决
一、问题描述
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命令进行封装,远看可以解决问题时,代码实现:
- stringRedisTemplate.multi();
- stringRedisTemplate.delete("test");
- stringRedisTemplate.opsForValue().set("test","2");
- stringRedisTemplate.exec();
结果保 错误:
我们查询multi、delete等源代码,发现会执行RedisTemplate类中execute()方法进行跟踪发现 RedisCallback中doInRedis获取的RedisConnection每次都是新的,所以才导致该问题。
分析Redis源代码:
我们查看multi实现
三、解决方案
只能自己实现RedisCallBack底层,采用RedisTemplate的SesionCallback来完成在同一个Connection中,完成多个操作的方法:
- SessionCallback<Object> sessionCallback=new SessionCallback<Object>(){
- @Override
- public Object execute(RedisOperations operations) throws DataAccessException{
- operations.multi();
- operations.delete("test");
- operations.opsForValue.set("test","2");
- Object val=operations.exec();
- return val;
- }
- }
- StringRedisTemplate.execute(sessionCallback);
RedisTemplate实现事物问题剖析和解决的更多相关文章
- C#里面的事物回滚,解决同步数据插入时出现重复数据
什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...
- 剖析和解决Python中网络粘包的正确姿势
目录 1.粘包及其成因 1.1.粘包产生 1.2.粘包产生的原因 2.尝试解决粘包 2.1.指定数据包的长度 2.2.固定数据包的长度 2.3.用函数实现多次调用发送数据 3.解决粘包问题的正确姿势 ...
- Springboot与ActiveMQ、Solr、Redis中分布式事物的初步探索
Springboot与ActiveMQ.Solr.Redis中分布式事物的初步探索 解决的场景:事物中的异步问题,当要求数据库与solr服务器的最终一致时. 程序条件: 利用消息队列,当数据库添加成功 ...
- Redis 事物、悲观、乐观锁 (详细)
1,概论 事物这东西相信大家都不陌生吧,在学习Spring,Mybatis等框架中, 只要是涉及到数据存储和修改的,都会有事物的存在, 废话就不多说了下面我们来简单的介绍下Redis事物以及锁. 2, ...
- 集成Spring事物管理
什么是事物 事物是访问数据库的一个操作序列,数据库应用系统通过事物集来完成对数据库的存取.事物的正确执行使得数据库从一种状态转换为另一种状态. 事物必须服从ISO/IEC所制定的ACID原则.ACID ...
- Idea使用记录--添加Problems&&解决Autowired报错could not autowire
今天在使用Idea的时候,发现Idea在整个每次找到错误代码非常不方便(Idea如果类中有错误,没有打开过类并不会提示,比如构建工程后缺少jar包问题).我想快速看到工程哪里出问题类似于eclipse ...
- CDN高级技术专家周哲:深度剖析短视频分发过程中的用户体验优化技术点
深圳云栖大会已经圆满落幕,在3月29日飞天技术汇-弹性计算.网络和CDN专场中,阿里云CDN高级技术专家周哲为我们带来了<海量短视频极速分发>的主题分享,带领我们从视频内容采集.上传.存储 ...
- JDBC中的事物处理
一项事物是由一个或是多个操作所组成的一个不可分割的工作单元.我们通过提交commit()或是回退rollback()来结束事务的操作. JDBC的事物处理包括三个方面:1:自动提交模式: 2:事务隔离 ...
- 浅谈,seata在使用feign-url通过域名调用时分布式事务不生效的问题及解决
浅谈,seata在使用feign-url通过域名调用时分布式事务不生效的问题及解决 在前几个月时,我们项目出现了分布式事务的问题,那么什么是分布式事务问题呢,简单的说,我们有俩服务A和B,它们对应 ...
随机推荐
- Oracle PLSQL Demo - 12.定义包体[Define PACKAGE BODY]
CREATE OR REPLACE PACKAGE BODY temp_package_demo is FUNCTION f_demo(userid NUMBER) RETURN BOOLEAN IS ...
- 在开发中写一些tool来提升自己的效率
比如说,我在调试一个web-project的时候,因为eclipse默认编译好的.class文件放在/build/classes/中,但是我希望随时把这些class文件放到/WEB-ROOT/WEB- ...
- .Net应该学什么怎么学(二)
更新时间:2012年06月05日18时23分 来源:传智播客.Net 接上篇<[我来解惑].Net应该学什么怎么学(一)>. 二.C#面向对象基础 初学者学面向对象的时候没必要(也做不到) ...
- datagridview添加行
添加明细按钮 DataRow dRow = DtDetail.NewRow(); dRow["PriceId"] = ConvertUtil.GetIntFromObject(dr ...
- 【C#】POST请求参数含中文,服务器解析得到乱码
问题:POST请求参数含有中文,已将含中文的string以UTF-8编码格式转为byte[],并写入到请求流中,但服务器收到数据后以UTF-8解码,得到的依然是乱码! 百度到了以下方法,但依然无法解决 ...
- 抽取、转换和装载介绍(三)ETL系统的34个子系统
这部分对ETL系统的架构中34个关键子系统进行分类.ETL其实可以分为下面四个步骤: 抽取.在ETL环境中从源系统收集原始数据并且在对任何对数据的重要重构发生之前都将数据写入磁盘.子系统1到子系统3都 ...
- Ubuntu下安装Apache
Ubuntu为我们提供了 su apt-get install 命令,通过它你可以很方便地安装一些软件,这些软件是放在Ubuntu放置在各个地方的服务器上面,如果你想安装的软件是比较常见的,一般都可以 ...
- 线程安全,有状态,无状态的对象<转>
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.另外 ...
- Android自己定义控件--圆形进度条(中间有图diao)
智能家居越来越流行,在智能家居中我们常要表现一些数据的百分比 圆形度条中间加个图是一种很流行的自己定义View 1.第一步 你首先须要对类进行继承View public class CirclePro ...
- StarRTC , AndroidThings , 树莓派小车,公网环境,视频遥控(一)准备工作
原文地址:http://blog.starrtc.com/?p=48 啥也不说,先来个视频看看效果 视频播放器 00:00 00:54 概述为了体现StarRTC的实时音视频传输能 ...