一、事务

一般来说,事务必须满足4个条件,也就是我们常说的ACID:

1)Atomicity 原子性:一个事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间的某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像是这个事务从来没有执行一样。

2)Consistency 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须符合所有预设原色,者包含资料的精确度、串联性以及后续的数据库可以自发性地完成预定工作。

3)Isolation 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交、读提交、可重复读和串行化。

4)Durability 持久性:事务处理以后,对数据的修改就是永久的,即便系统故障也不会丢失。

二、redis事务

从本质上来说,redis的事务其实不能算是事务,或者说它不遵循ACID原则,只是将一组命令置入队列,然后像执行一个命令一样执行一组命令。可是它并不保证所有命令完整执行,也不支持事务回滚。因此,当一个事务中其中一个命令发生错误,其它命令还是会被执行。这听起来有些奇怪,不过redis给出了相应的解释。后面我们会提到。

redis事务有两个原则:

1)一个事务包含一组命令,当事务在执行期间不会有其它客户端的命令穿插执行。这意味着,这组命令在执行期间类似于一个隔离的命令操作。

2)事务通过multi命令创建,multi之后的命令将会进入执行队列,当exec命令执行的时候,会将进入队列的命令全部按顺序执行,并返回顺序的结果。这里要注意:1)如果redis在multi执行之前发生如硬件崩溃等错误,那么所有东西都不会被执行。2)如果redis在exec执行之后发生崩溃等错误,那么所有都洗都会被执行。3)当使用AOF持久化策略的时候,会将事务写入日志文件,如果写入过程发生崩溃等错误,那么redis重新启动加载日志的时候会发生错误并退出(可以使用redis-check-aof)工具解决。

三、使用

我们看一个简单的示例

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 23
QUEUED
127.0.0.1:6379> set name lay
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK

multi: 开启一个事务

set age 23 命令入队

set name lay 命令入队

exec: 事务执行

返回数据结果

四、错误

在一个事务开始到执行结束期间可能发生很多问题,主要分为如下两种:

1)exec执行之前发生错误,如发生语法错误。

2)exec执行期间发生错误,如操作的值类型错误。

一般上,如果exec执行之前发生错误,那么客户端会将当前的事务取消、队列的命令清除。如果在exec执行期间发生错误,那么其它命令还会继续执行,并不会回滚。

五、为什么redis不支持事务回滚?

熟悉关系型数据库的你应该很清楚事务回滚,当看到redis不支持回滚肯定会觉得很奇怪。redis官方给出解释原文如下:

  • Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.
  • Redis is internally simplified and faster because it does not need the ability to roll back.

主要是两点:

1)redis官方认为,导致redis出错的情况一般是在开发期间就可以发现的,如语法错误,操作的值类型不对。而不应当把研发上的错误在生产环境里检查,而真的在生产环境出现的错误,其实通常是事务回滚也无法解决的。

2)事务带来的开销是性能的损失,redis本身是单线程架构,追求内存的高效,所以事务回滚并不符合它的宗旨。

总结一下:redis容许发生一些影响不大的错误(如空值什么的),虽然产生使用上的限制,但减少了开销,提高了性能。

六、事务执行条件

redis中有一个watch命令,它可以监听key的变化,如果事务在执行之前key的值由其它客户端改变,那么当前事务将会被取消、队列命令也会被清除。

如:

client1开启事务:

127.0.0.1:6379> watch age
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 25
QUEUED

client2改变数据:

127.0.0.1:6379> set age 27
OK

client1执行exec:

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>

返回nil,当前事务已经被取消了

七、事务命令

discard: 取消

exec: 执行

multi: 开启

unwatch: 取消监听

watch: 监听

详细参考官方文档:https://redis.io/topics/transactions

八、lua

redis内嵌了lua模块,这里简单提一下lua的执行也是事务性的,在redis中可以用lua来实现事务,并且通常lua更加的简单和快速。

redis(4)事务的更多相关文章

  1. Redis的事务

    Redis对事务的支持是部分支持,不想oracle,要么都成功要么都失败,Redis可以部分成功部分失败 1 是什么: 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺 ...

  2. Redis笔记(五)Redis的事务

    >>关系型数据库的事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消. Atomic(原子性): 一个事务(transaction)中的 ...

  3. redis的事务(简单介绍)

    1.简单描述 redis对事务的支持目前还是比较简单.redis只能保证一个client发起的事务中的命令是可以连续的执行,而中间不会插入其他client的命令.由于redis是但现场来处理所有cli ...

  4. Redis的事务功能详解

    Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...

  5. Redis的事务和watch

    redis的事务 严格意义来讲,redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的. redis中的事务定义 Redis中的事务(transaction)是一组命令的集合. 事务同 ...

  6. spring中jedis对redis的事务使用注意总结

    spring的@Transactional不支持redis的事务,并且redis的事务和其它关系型数据库的事务概念不是太一样,redis事务不支持回滚,并且一条命令出错后,后面的命令还会执行. 所以不 ...

  7. Redis保证事务一致性,以及常用的数据结构

    reids命令可以参考中文官网:http://redis.cn/commands.html 关于reids的使用,可以封装到工具类进行调用: Redis的工具类:JedisAdapter 除了数据结构 ...

  8. Redis(十一):Redis的事务功能详解

    相关命令 1. MULTI 用于标记事务块的开始.Redis会将后续的命令逐个放入队列中,然后才能使用EXEC命令原子化地执行这个命令序列. 这个命令的运行格式如下所示: MULTI 这个命令的返回值 ...

  9. 第四章· Redis的事务、锁及管理命令

    一.事务介绍 二.Redis乐观锁介绍 三.Redis管理命令 一.事务介绍 Redis的事务与关系型数据库中的事务区别 1)在MySQL中讲过的事务,具有A.C.I.D四个特性 Atomic(原子性 ...

  10. $Django python中使用redis, django中使用(封装了),redis开启事务(管道)

    一 Python操作Redis之普通连接 #先安装 pip3 install redis import redis r = redis.Redis(host='127.0.0.1', port=637 ...

随机推荐

  1. css3箭头

    <!DOCTYPE html> <html lang="en" class="muui-theme-webapp-main"> < ...

  2. CentOS下 Yum 损坏与重建

    yum报错error: rpmdb open failed 这种情况一般是由于rpm数据库被损坏导致的,可按照下述方法重建yum数据库: cd /var/lib/rpm/ rm -rf __db.* ...

  3. spring框架里面的注入?

    在Spring框架里面注入可以通过1.setter方法注入:2.构造器注入:3.注入对象 在配置文件中配置如下: 前面两者不能同时注入: 入 如果前两者同时注入将会报错 将注入修改以后,如下图: 修改 ...

  4. 最新的PHP trait使用方法详解

    说通俗点,PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的. 具体案例,查看php中文网这篇文章.http:// ...

  5. 如何在NSDocumentDirectory内新建一个文件夹

    iOS下载文件一般保存到NSDocumentDirectory内,但是为了更好整理文件内容,那就要自定义的生成一些文件夹,和做一些删除文件夹的操作. - (NSString *)pathToPatie ...

  6. P2472 [SCOI2007]蜥蜴

    传送门 求无法逃离的蜥蜴总数的最小值就是求最多逃离的蜥蜴总数 所以显然考虑最大流,一个流量的路径就相当于一只蜥蜴逃离的路径 发现每个位置有一个最大经过次数,所以把每个位置拆成两个点$x,y$,$x$ ...

  7. vue html页面打印功能vue-print

    vue项目中,HTML页面打印功能.在项目中,有时需要打印页面的表格, 在网上找了一个打印组件vue-print-nb 使用方式 安装 npm install vue-print-nb --save ...

  8. my.工坊_ZZ

    1.查了下,可以将 考古升上去,但是 还是使用 2级的考古技能,这样比较赚,高级的反而不赚.但是看到有人说 考古升到 3/4 不能再用 洛阳铲 了. 于是有了两种情况,我暂定的做法:先将 考古升到2级 ...

  9. 使用Django-environ管理多个配置

    使用Django-environ管理多个配置 https://django-environ.readthedocs.io/en/latest/

  10. win10操作系统系统,小米路由器,小米3 的问题

    注意 , 置顶 单独一篇 : { win10  局域网共享 小米路由器,操作盘太卡 } 开发中用专业版 , 别用家庭版 比如有远程桌面程序 和 HV 虚拟机 查看激活信息 和 是不是永久激活 参考 h ...