一、事务

一般来说,事务必须满足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. jquery源码解析:jQuery扩展方法extend的详解

    jQuery中要扩展方法或者属性都是通过extend方法实现的.所谓的jQuery插件也是通过extend方法实现的. jQuery.extend扩展的是工具方法,也就是静态方法.jQuery.fn. ...

  2. h5聊天工具的开发过程及思路

    这个产品的主要技术栈有,网易nim即时通信,vue-cli,muse-ui 1.在拿到这个需求时,脑袋里空的,什么想法都没有,完全懵逼,进了网易云通信的官网api查看,由于我做的是客户端的,所以重点看 ...

  3. Numpy中扁平化函数ravel()和flatten()的区别

    在Numpy中经常使用到的操作由扁平化操作,Numpy提供了两个函数进行此操作,他们的功能相同,但在内存上有很大的不同. 先来看这两个函数的使用: from numpy import * a = ar ...

  4. Springboot第三篇:与前端fetch通信(关于前端传输json数据上传文件等等前后端的处理)

    关于前端接口传递的方法,推荐按以下使用: 若要在服务器上创建资源,推荐使用POST方法 若要检索某个资源,推荐使用GET方法 若要更新资源,推荐使用PUT方法 若要删除某个资源,推荐使用DELETE方 ...

  5. java中的Lamdba表达式和Stream

    基于JDK 1.8 1.循环: // 以前的循环方式 for (String player : players) { System.out.print(player + "; ") ...

  6. 网络基础 01_OSI网际互联

    1 通信概述 网络是用物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的. 通信是人与人之间通过某种媒体进行的信息交流与传递. 网络通信是通过网络将各个孤立的设备进 ...

  7. jdbc连接oracle的url的三种写法

    JDBC 链接oracle的三种URL写法 1.普通SID方式     jdbc:oracle:thin:username/password@x.x.x.1:1521:SID 2.普通ServerNa ...

  8. PIE_SDK.NET功能表

  9. google hack使用集锦

    转载:https://blog.csdn.net/weixin_42127015/article/details/84472777 关于google hack的几个基础过滤器使用[请务必谨记,过滤器虽 ...

  10. selenium+Python(事件)

    1.操作测试对象前面讲到了不少知识都是定位元素,定位只是第一步,定位之后需要对这个元素进行操作.鼠标点击或者键盘输入,这要取决于我们定位的是按钮还输入框.一般来说,webdriver 中比较常用的操作 ...