Redis3.0.x 事务

基本概念

multi,exec,discard,watch 是 Redis 事务的基础,它们允许一步执行一组命令,有两个重要保证:

  • 事务中的所有命令都被序列化并顺序执行。在 Redis 事务的执行过程中,永远不会执行另一个客户端发出的请求。
  • 所有命令要么都被执行,要么都不被执行。

Redis 以 乐观锁的形式对这两个保证提供支持,其方式和 CAS(Check And Set,检查后设置)操作非常相似。

悲观锁:顾名思义,就是每次去拿数据的时候都认为会被修改,所以每次都会加上锁,这样再去拿数据的时候就会被阻塞,直到拿到锁。比如行锁、表锁、读写锁等,都是在操作之前先加上锁。

乐观锁:顾名思义,就是每次去拿数据的时候都认为不会被修改,所以都不会上锁,但是在更新的时候会判断在此期间有没有更新这个数据,可以使用版本控制等策略。一般使用于多读少写的应用。

版本控制策略:执行更新的前提是提交的版本必须大于当前记录的版本。

基本命令

  • MULTI:标记一个事务块的开始
  • EXEC:执行事务块内所有的命令
  • DISCARD:放弃执行事务块内所有的命令
  • WATCH key [key...]:监视一个或多个 key,如果在事务执行之前 这些 key 被其他命令改动,那么事务将被打断
  • UNWATCHL:取消 WATCH 对 所有 key 的监视

事务使用

正常执行

  1. 127.0.0.1:6379> multi
  2. OK
  3. 127.0.0.1:6379> set k1 v1
  4. QUEUED
  5. 127.0.0.1:6379> get k1
  6. QUEUED
  7. 127.0.0.1:6379> set k2 v2
  8. QUEUED
  9. 127.0.0.1:6379> exec
  10. 1) OK
  11. 2) "v1"
  12. 3) OK

放弃事务

  1. 127.0.0.1:6379> multi
  2. OK
  3. 127.0.0.1:6379> set k3 v3
  4. QUEUED
  5. 127.0.0.1:6379> get k3
  6. QUEUED
  7. 127.0.0.1:6379> set k4 v4
  8. QUEUED
  9. 127.0.0.1:6379> discard
  10. OK
  11. 127.0.0.1:6379> get k3
  12. (nil)
  13. 127.0.0.1:6379> get k4
  14. (nil)

“编译”异常

  1. 127.0.0.1:6379> multi
  2. OK
  3. 127.0.0.1:6379> set name parzulpan
  4. QUEUED
  5. 127.0.0.1:6379> get name
  6. QUEUED
  7. 127.0.0.1:6379> set eamil
  8. (error) ERR wrong number of arguments for 'set' command
  9. 127.0.0.1:6379> exec
  10. (error) EXECABORT Transaction discarded because of previous errors.
  11. 127.0.0.1:6379> get name
  12. (nil)

类似 Java 中的编译时异常,比如语法错误、内存不足等。这样情况下,命令无法排队,Redis 将拒绝执行事务,并且在 EXEC 期间还会返回错误并自动丢弃该事务。

“运行”异常

  1. 127.0.0.1:6379> multi
  2. OK
  3. 127.0.0.1:6379> set k3 v3
  4. QUEUED
  5. 127.0.0.1:6379> get k3
  6. QUEUED
  7. 127.0.0.1:6379> set a 1
  8. QUEUED
  9. 127.0.0.1:6379> get a
  10. QUEUED
  11. 127.0.0.1:6379> incr k3
  12. QUEUED
  13. 127.0.0.1:6379> exec
  14. 1) OK
  15. 2) "v3"
  16. 3) OK
  17. 4) "1"
  18. 5) (error) ERR value is not an integer or out of range

类似 Java 中的运行时异常,比如类型错误等。这种情况下,命令可以排序,Redis 将执行事务,只不过会对应的返回错误信息。

监控使用

初始化信用卡可用余额和欠额:

  1. 127.0.0.1:6379> set balance 1000
  2. OK
  3. 127.0.0.1:6379> set debt 0
  4. OK
  5. 127.0.0.1:6379> multi
  6. OK
  7. 127.0.0.1:6379> decrby balance 100
  8. QUEUED
  9. 127.0.0.1:6379> incrby debt 100
  10. QUEUED
  11. 127.0.0.1:6379> exec
  12. 1) (integer) 900
  13. 2) (integer) 100
  14. 127.0.0.1:6379> get balance
  15. "900"
  16. 127.0.0.1:6379> get debt
  17. "100"

无监控键更改。先监控键在开启事务,保证交易金额变动在同一个事务里:

  1. 127.0.0.1:6379> watch balance
  2. OK
  3. 127.0.0.1:6379> multi
  4. OK
  5. 127.0.0.1:6379> decrby balance 100
  6. QUEUED
  7. 127.0.0.1:6379> incrby debt 100
  8. QUEUED
  9. 127.0.0.1:6379> exec
  10. 1) (integer) 800
  11. 2) (integer) 200

所有 监控键 都会具有从调用开始一直到调用EXEC为止 监视更改的效果。即执行完 EXEC,监控消失。


有监控键更改。开启多个终端,模拟更改监控键。

  1. 127.0.0.1:6379> get balance
  2. "800"
  3. 127.0.0.1:6379> watch balance
  4. OK
  5. 127.0.0.1:6379> set balance 900
  6. OK
  7. 127.0.0.1:6379> multi
  8. OK
  9. 127.0.0.1:6379> decrby balance 100
  10. QUEUED
  11. 127.0.0.1:6379> incrby debt 100
  12. QUEUED
  13. 127.0.0.1:6379> exec
  14. (nil)
  15. 127.0.0.1:6379> get balance
  16. "900"
  17. 127.0.0.1:6379> get debt
  18. "200"

监控键受到监控,以检测其更改。如果在 EXEC 命令之前至少更改了一个监视键,则整个事务将中止,并且 EXEC 返回 Null 答复以通知该事务失败。


有监控键更改,但更改后解除监控。开启多个终端,模拟更改监控键。

  1. 127.0.0.1:6379> get balance
  2. "800"
  3. 127.0.0.1:6379> get debt
  4. "200"
  5. 127.0.0.1:6379> watch balance
  6. OK
  7. 127.0.0.1:6379> set balance 900
  8. OK
  9. 127.0.0.1:6379> unwatch
  10. OK
  11. 127.0.0.1:6379> multi
  12. OK
  13. 127.0.0.1:6379> set balance 700
  14. QUEUED
  15. 127.0.0.1:6379> set debt 300
  16. QUEUED
  17. 127.0.0.1:6379> exec
  18. 1) OK
  19. 2) OK
  20. 127.0.0.1:6379> get balance
  21. "700"
  22. 127.0.0.1:6379> get debt
  23. "300"

如果监控键受到监控,在更改之后,使用 UNAWTCH 解除监控,那么事务将正常执行。

为什么 Redis 不支持回滚

Redis 中不保证原子性,不支持回滚,即部分支持事务。主要有以下两个原因:

  • 仅当使用错误的语法(并且在命令排队期间无法检测到该问题)或针对包含错误数据类型的键调用 Redis 命令时,该命令才能失败。这实际上意味着失败的命令是编程错误的结果,还有一种很可能在开发过程中而不是生产过程中发现的错误。
  • Redis 在内部得到了简化和优化,所以它不需要回滚的能力。

Redis 脚本和事务

一个 Redis 的脚本是定义事务性的,所以可以用 Redis 的事务做的,也可以用一个脚本做,并且使用脚本会更简单,更快速。

练习和总结

【Redis3.0.x】事务的更多相关文章

  1. 【Redis3.0.x】NoSql 入门

    Redis3.0.x NoSql 入门 概述 NoSQL(Not Only SQL ),即不仅仅是 SQL,泛指非关系型的数据库.NoSQL 数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑 ...

  2. 【Redis3.0.x】实战案例

    Redis3.0.x 实战案例 简介 <Redis实战>的学习笔记和总结. 书籍链接 初识 Redis Redis 简介 Redis 是一个速度非常快的键值对存储数据库,它可以存储键和五种 ...

  3. Redis3.0 配置文件说明

    背景: 以前有篇文章已经结果过了,现在复习一下,对Redis3.0进行说明: 参数说明: #redis.conf # Redis configuration file example. # ./red ...

  4. redis3.0.6安装(linux和windows)

    官网上描述安装方法如下:$ wget http://download.redis.io/releases/redis-3.0.6.tar.gz$ tar xzf redis-3.0.6.tar.gz$ ...

  5. Redis3.0.1 Stable版本的集群部署(Mac)

    本文档基于如下原始文档(CentOS)创建: http://blog.csdn.net/xu470438000/article/details/42971091 修改了一些路径的错误,补全了一些命令执 ...

  6. Redis3.0.7 cluster/集群 安装配置教程

    1.前言 环境:CentOS-6.7-i386-LiveDVD 安装的CentOs系统 节点: 6个节点,3个主节点.3个从节点(由于redis默认需要3个主节点,如果想每个主节点有一个从节点,这是最 ...

  7. CentOS完美搭建Redis3.0集群并附测试

    线上的统一聊天和推送项目使用的是redis主从,redis版本2.8.6 redis主从和mysql主从目的差不多,但redis主从配置很简单,主要在从节点配置文件指定主节点ip和端口:slaveof ...

  8. redis3.0.0 集群安装详细步骤

    Redis集群部署文档(centos6系统) Redis集群部署文档(centos6系统) (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对 ...

  9. MAC air 安装redis-3.0.6

    redis版本: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 16.0px Menlo; color: #c33720; background-colo ...

随机推荐

  1. ado.net使用sqlparameter的方式

    使用sqlparameter的方式,最终执行的sql语句 exec sp_executesql N'select top 1 ID,ZhangHu,MiMa,RID,ShiJian,EndTime,I ...

  2. 哔哩哔哩直播录制工具v1.1.18

    软件介绍 看直播有时候非常精彩想要录制下来,或者非常喜欢某个主播想录制下直播全程,可去找录制软件的时候却发现有这样那样的问题,导致一番操作不尽人意.但是现在<B站直播录制工具>可以完美解决 ...

  3. 基于menu小插件探索工程实践

    目录 一.准备工作 1.C/C++环境搭建 2.VSCode的配置 (1) 安装插件: (2) 设置配置文件: 二.工程化编程实战 1.模块化设计 2.可重用设计:进一步抽象 menu的进一步优化 可 ...

  4. 【Django Python版本对应】

    使用Python36 时应该使用Django版本1.11.4 pip install django==1.11.4 版本对应表: Django version Python versions 1.8 ...

  5. 20201213-1 HTML基本标签(一)

    > HTML 基本结构 <> </> 标签对   > 一个 HTML 文档由 4 个基本部分组成: 文档声明:<!DOCTYPE HTML>声明这是一个 ...

  6. Python 学习笔记 之 01 - 基础总结

    数据类型 整数 十六进制和八进制使用0开头,0x12f, 010 浮点数 可以用科学记数法,如1.23x10^9 可以写成 12.3e8 ,0.000012可以写成 1.2e-5 空值 用None表示 ...

  7. 精尽Spring MVC源码分析 - HandlerMapping 组件(四)之 AbstractUrlHandlerMapping

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  8. js上 五、运算符-1

    5.1.认识运算符 什么是运算符? 运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算. 运算符的应用: 购物车:计算总价,数量: **Js ** 中有哪些运算符? 算术运算符.赋值运算符 ...

  9. 图片放大缩小的zoom.js

    1 +function ($) { "use strict"; 2 3 /** 4 * The zoom service 5 */ 6 function ZoomService ( ...

  10. 类818tu.c微信小说分销系统设计之定时模板消息源码

    近期将出个系列讲解开发过程,同时作为此系统的开发记录吧,万能的博客园,本边讲解如何发送模板消息,并且能够定时发送,下一篇讲解如何处理多个公众号的网页授权登录问题 [后台]http://xiaoshuo ...