一、事务

一般来说,事务必须满足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. collections中的defaultdict

    用类型 用函数返回值 嵌套的dict from collections import defaultdict def tree(): return defaultdict(tree) c = defa ...

  2. JavaScript数组升降序排列、最大值、最小值等

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. [Winter Vacation] 守护,守望

    最近总是堕落......想好了,不如在百无聊赖之时写一些心底的话,让它们最终不归于尘土吧. 有了想要守护一个人的信念与想法,然而有没有资格却还没有人能够说清楚,下断言.这可真是可悲了,总不能笃定着对方 ...

  4. Python strip()函数用法

    Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数: strip 同时去掉左右两边的空格lstrip 去掉左边的空格rstrip 去掉右边的空格 具体示 ...

  5. [转] HTTP状态码错误代码

    一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 详细分解: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 ...

  6. php-elasticsearch bulk批量插入数据

    1.单条插入 <?php include '../vendor/Elasticsearch/autoload.php'; $a['hosts'] = array( #需要用户名时 http:// ...

  7. 使用cookie下次自动登录

    登录时勾选了自动登录处理: 1.加密账号和IP,保存在cookie中,cookie('auto', $value, $time) 2.解密cookie,取出账号和上次IP,判断上次IP==当前IP.账 ...

  8. linux的sed(增删改查)使用方法

    sed的增删改查的基本操作 参考:https://www.cnblogs.com/0zcl/p/6855740.html 01:增(a) 2个sed命令,分别是:(这些操作都是在内存中进行的,所以不会 ...

  9. bzoj2959: 长跑(LCT+并查集)

    题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...

  10. [Java基础]-- Java GC 垃圾回收器的分类和优缺点

    https://blog.csdn.net/high2011/article/details/80177473?utm_source=blogxgwz2 参考:elasticsearch实战-使用G1 ...