关系型数据库事务的作用是保证并发访问下数据的一致性,Redis事务有些不同,由于Redis是单线程的处理来自client的指令,所以Redis所有命令的执行都是原子性的,举一个简单的例子,单个Redis服务器下,并发地执行INCR命令,也不会返回相同的结果。
所以Redis事务的意义在于保证命令的批量顺序执行,并且事务执行期间,Redis不会执行来自client的其他请求。有一点需要注意的是,。如果有命令执行失败,还是会继续执行剩下的命令,因为Redis没有异常回滚。
对“Redis事务命令要么全部执行,要么全部不执行”这句事实的理解:如果有命令执行失败,并不是中断事务,而是继续执行剩下的指令,因为Redis不支持异常回滚。全部不执行的情况有 1.没有执行EXEC命令 2.WATCH的key发生改变 3.DISCARD命令放弃事务。本质上开启事务后,所有输入的命令都被缓存在一个队列中,一旦EXEC,队列里的指令被一条一条的执行。
关于事务的API
- MULTI 开启事务
- EXEC 执行任务队列里所有命令,并结束事务
- DISCARD 放弃事务,清空任务队列,全部不执行,并UNWATCH
- WATCH key [key1] MULTI执行之前,指定监控某key,如果key发生修改,放弃整个事务执行
- UNWATCH 手动取消监控
Spring Data Redis 事务问题
RedisTemplate来操作Redis,关于事务操作的时候会有问题:
redisTemplate.multi(); redisTemplate.opsForValue().increment("xxx",1); redisTemplate.opsForValue().increment("ttt",1); redisTemplate.exec();
调用会报一个错误“No ongoing transaction. Did you forget to call multi? ”查了下,RedisTemplate操作事务不能理所当然地像原生API那么写,其实RedisTemplate的事务需要自己实现一个SessionCallBack来做事务,所以要这么写SessionCallback sessionCallback = new SessionCallback() { @Override public Object execute(RedisOperations redisOperations) throws DataAccessException { redisOperations.multi(); // TODO: 2017/11/20 命令1 // TODO: 2017/11/20 命令2 // TODO: 2017/11/20 命令3 return redisOperations.exec(); } }; redisTemplate.execute(sessionCallback);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架