笔者事务相关文章链接:Redis WATCH事务监视机制与回滚

什么是Redis事务

Redis的事务就是一组命令的集合。Redis提供了将一组命令打包集合的方法,并且能够一次性、按顺序的执行多个命令,事务执行期间,服务器不会中断事务改为执行其他客户端的命令请求,只有事务中所有命令都执行完毕后,服务器才会处理其他客户端的命令请求。

在开始说明事务的使用与基本流程之前,需要先说明关于Redis和事务的两个问题。

Redis事务具有原子性吗?

先给出结论:Redis单条命令具有原子性,Redis事务是否具有原子性存在争议

笔者认为关于Redis事务原子性的争议存在的主要原因是对原子性定义不统一。

关于原子性的定义,首先操作不能被中断是公认的必要条件,分歧的点在于,一说认为操作要么全部执行,要么全部不执行才能说操作具有原子性,另一说认为操作要么全部执行成功,要么全部执行失败才能说操作具有原子性。

在关系型数据库中,原子性体现在要么事务中的命令全部成功执行,要么全部不执行,事务中任一命令出现错误,会回滚此前已经执行了的命令。

在Redis中,只能保证事务不可中断,但若事务执行过程中某条命令出现错误,Redis不会回滚已经执行了的命令,因此Redis只做到了要么不执行,要么全部执行,但不能保证出现事务内命令错误时全部执行失败。

因此,无论是哪种对于原子性的理解,关系型数据库中的事务都满足,即关系型数据库中事务是具有原子性的。如果认同前者原子性定义(要么全做,要么全不做),那么可以说Redis的事务具有原子性,如果认同后者的原子性定义(要么全成功,要么全失败),那么Redis的事务不具有原子性

Redis支持回滚吗?

在Redis官方文档中明确指出,Redis不支持回滚

笔者在浏览其余关于Redis回滚问题的博文时,发现部分文章内提及,使用WATCH关键字监控事务时,发现被监控的数据库键被修改时,会进行回滚。产生这种误解是由于没有理解WATCH的判断时机,WATCH早在事务将要实际执行前就会进行判断,若被监控的数据库键被修改,整个事务都不会执行,而非执行到具体被监控的数据库键操作时才进行判断。

事务的执行流程

事务从开始到结束共经历三个阶段:

  1. 事务开始
  2. 命令入队
  3. 事务执行

事务开始

首先明确一点,底层实现中每个Redis客户端内都有一个用于标识事务状态的属性。

Redis中,使用MULTI命令来开启一个事务,命令执行时会判断当前客户端的事务状态,如果当前客户端事务状态已经开启,返回错误并提示事务不可嵌套,若客户端事务未开启,则修改客户端状态开启并返回OK。

演示如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> multi
(error) ERR MULTI calls can not be nested

命令入队

同样,Redis每一条命令执行前都会判断客户端事务标识状态,如果事务没有开启,命令自然直接执行,事务开开启时,不会执行执行命令,会将命令入队。

演示如下:

127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 2
QUEUED

命令执行

使用EXEC命令来执行当前事务,事务内的命令会按照入队顺序依次执行,事务执行完毕或执行失败时会改变当前客户端事务标识状态,事务未开启时使用EXEC命令会报错。

完整演示如下:

127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set b 1
QUEUED
127.0.0.1:6379> incr a
QUEUED
127.0.0.1:6379> exec
1) OK
2) (integer) 2
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI

放弃事务

Redis提供了DISCARD命令来放弃当前事务,成功放弃事务时返回OK,事务为未开启状态时返回错误。

演示如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI

事务对于错误的处理

Redis事务有两种可能的错误

命令入队时错误

第一种可能的情况是在命令入队阶段,键入了错误的命令,Redis事务对此的处理是弃置整个事务。

演示如下:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> abc
(error) ERR unknown command `abc`, with args beginning with:
127.0.0.1:6379> set b 1
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> mget a b
1) (nil)
2) (nil)

由以上演示可见,事务内包含错误命令时,会直接弃用整个事务,提示信息为由于此前(命令入队)的错误,已经放弃执行事务。

命令执行时错误

第二种可能的错误是,事务内的命令格式全部正确,但执行时出现错误,比如incr自增的对象不能被转换为整数,对于此种情况,Redis的处理是,事务内任一命令的执行错误不会影响其它命令的正常执行,更不存在事务回滚这一操作

演示如下:

127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> set b string
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr a
QUEUED
127.0.0.1:6379> incr b
QUEUED
127.0.0.1:6379> exec
1) (integer) 2
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> mget a b
1) "2"
2) "string"

总结

事务流程

流程图总结如下:

Redis事务的ACID性质

原子性

基本同文首解释的相同,不过多赘述。

首先Redis的事务一定能保证执行不会被中断。但Redis只能保证事务内命令要么全部执行,要么全部不执行,不能保证全部执行成功或全部执行失败,Redis事务是否具有原子性存在争议。

一致性

Redis能够保证,Redis事务在开始前和结束后数据库的完整性不会被破坏,因此Redis事务具有一致性。

隔离性

Redis能够保证,当数据库中有多客户端同时执行事务时(并发),各事务间不会互相影响,在并发状态下执行的事务和串行时执行事务的结果完全相同,Redis事务具有隔离性。

持久性

Redis事务本身没有持久化的操作,但如果服务器开启了AOF或者RDB的持久化,可以认为Redis事务具有持久性。

Redis 事务机制深入浅出相关推荐

  1. Redis事务机制 -Redis 核心技术与实战

    事务是数据库的一个重要功能.所谓的事务,就是指对数据进行读写的一系列操作.事务在执行时,会提供专门的属性保证,包括` 原子性(Atomicity) 一致性(Consistency) 隔离性(Isola ...

  2. redis 学习 --->>> 9、Redis 事务机制

    9.Redis 事务机制 1.事务的定义 Redis 事务是一个单独的隔离操作: 事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. Redis事务 ...

  3. 16-SpringBoot之Redis(三)——Redis事务机制

    SpringBoot之Redis(三)--Redis事务机制 1. Redis 事务执行过程 2. 开启事务支持 3. 测试 4. 测试结果说明 5. 源码下载 1. Redis 事务执行过程 Red ...

  4. Redis事务机制和分布式锁

    Redis事务机制 严格意义来讲,Redis的事务和我们理解的传统数据库(如mysql)的事务是不一样的:Redis的事务实质上是命令的集合,在一个事务中要么所有命令都被执行,要么所有事物都不执行. ...

  5. 图解Redis事务机制

    来自:Java中文社群 作为关系型数据库中一项非常重要的基础功能--事务,在 Redis 中是如何处理并使用的? 1.前言 事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只 ...

  6. Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现

    回到目录 Redis本身支持事务,这就是SQL数据库有Transaction一样,而Redis的驱动也支持事务,这在ServiceStack.Redis就有所体现,它也是目前最受业界认可的Redis驱 ...

  7. Redis实战 - 15 Redis事务机制和乐观锁实现

    文章目录 1. Redis事务简介 2. Redis事务的操作命令 3. Redis的事务回滚 4. Redis监控事务 1. Redis事务简介 在 Redis 中,也存在多个客户端同时向 Redi ...

  8. java redis事务机制_Redis 事务机制

    Redis 事务:可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序串行化执行而不会被其它命令插入,一次性.顺序性.排他性的执行一系列命令. 一.常用命令 [1] :开 ...

  9. Redis 事务机制实现

    1.首先,我们来看一下Redis中事物相关的指令, 命令原型        命令描述 MULTI   用于标记事务的开始,其后执行的命令都将被存入命令队列,直到执行EXEC时,这些命令才会被原子执行. ...

最新文章

  1. 自动分析源代码,创建函数地图展示调用关系
  2. Python 进程之间共享数据(全局变量)
  3. 架构设计贵在务实(转载)
  4. register_chrdev深入分析
  5. OpenLDAP / Ubuntu 18.04 下 docker 版安装
  6. python子进程关闭fd_如果创建了multiprocessing.Pool,Python子进程wait()将失败
  7. mondrain配置mysql_mondrian 4.7 源码部署(示例代码)
  8. Bootstrap(二)—格栅系统!
  9. Unreal Engine 4 编码规范
  10. 国产“电动牦牛”亮相,负重 160 公斤健步如飞!
  11. flask框架(四):通过局域网访问网站
  12. 【CSS】解决图片和盒子底部产生的缝隙问题
  13. 基于阈值和深度学习的玉米常见锈病严重程度自动模糊逻辑预测(工具+综述+玉米锈病严重程度数据集)
  14. python打乱列表的方法_python打乱列表
  15. php调用文章至首页,WP如何在首页调用分类文章列表的详细教程
  16. 关于DatetTime?
  17. 动态添加GRIDVIEW内容 和数据绑定
  18. 熊迈摄像头SDK二次开发:登录、截屏、录像等功能
  19. 【云游戏】云游戏的架构设计和技术实现
  20. Input用户输入完后再执行方法

热门文章

  1. VERIFY是什么意思
  2. SIP协议与视频通信
  3. express实现多级路由文件
  4. C++ vector类
  5. 12.Spring Bean是什么
  6. 【沟通的艺术】如何应对棘手的听众?
  7. ubuntu删除文件和文件夹的rm命令
  8. 温度传感器在LCD上显示代码
  9. 计算机二级在线报名进不去,全国计算机等级考试网上报名注意事项
  10. C语言中int类型及位、字节和字的介绍