作者 | video++极链科后端team刘聪
整理 | 包包
所谓事务(transaction) ,是指作为单个逻辑工作单元执行的一系列操作。事务必须满足acid原则(原子性、一致性、隔离性和持久性)。简单来说事务其实就是打包一组操作(或者命令)作为一个整体,在事务处理时将顺序执行这些操作,并返回结果,如果其中任何一个环节出错,所有的操作将被回滚。
在redis中实现事务主要依靠以下几个命令来实现:
redis事务从开始到结束通常会通过三个阶段:
1.事务开始
2.命令入队
3.事务执行
以下是一个最简单的redis事务流程:
第一步跟其他的关系型数据库类似,也是需要开启一个事务,在redis中的命令如下:
redis中使用multi命令标记事务的开始,可以理解为在传统关系型数据库中的begin trancation语句,redis将执行该命令的客户端从非事务状态切换成事务状态,这一切换是通过在客户端状态的flags属性中打开redis_multi标识完成, 我们看下redis中对应部分的源码实现:
在打开事务标识的客户端里,这些命令都会被暂存到一个命令队列里,不会因为用户会的输入而立即执行。
第二步就是执行事务内路基,即真正的业务逻辑:
最后一个阶段是提交事务(或者回滚事务):
这两个命令可被视为等同于关系型数据库中的commit/rollback语句。
这里需要注意的是,在客户端打开了事务标识后,只有命令:exec,discard,watch,multi命令会被立即执行,其它命令服务器不会立即执行,而是将这些命令放入到一个事务队列里面,然后向客户端返回一个queued回复 ;redis客户端有自己的事务状态,这个状态保存在客户端状态mstate属性中,mstate的结构体类型是multistate,我们看下multistate的定义:
我们再看下结构体类型multicmd的结构:
事务队列以先进先出的保存方法,较先入队的命令会被放到数组的前面,而较后入队的命令则会被放到数组的后面。
当开启事务标识的客户端发送exec命令的时候,服务器就会执行,客户端对应的事务队列里的命令,我们来看下exec 的实现细节:
最后我们再回顾一下事务本身的特性, 在传统关系型数据库中的事务必须依靠acid来保证事务的可靠性和安全性,在redis中事务总是具有一致性(consistency)和隔离性(isolation),并且当redis运行在某种特定的持久化模式下,事务也具有耐久性(durability); 但是并不总是能够保证原子性(atomicity),在正常状态下一个事务的所有命令是能按照原子性的原则执行的,但是执行的中途遇到错误,不会回滚,而是继续执行后续命令, 如下:
如果在set k2 v2处失败,set k1已成功不会回滚,set k3还会继续执行;redis的事务和传统的关系型数据库事务的最大区别在于,redis不支持事务的回滚机制,即使事务队列中的某个命令在执行期间出现错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止,我们看下面的例子:
redis的作者在事务功能的文档中解释说,不支持事务回滚是因为这种复杂的功能和redis追求的简单高效的设计主旨不符合,并且他认为,redis事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为redis开发事务回滚功能。所以我们在讨论redis事务回滚的时候,一定要区分命令发生错误的时候。
如何充电不会伤害到电池,手机充电的正确方法
特斯拉上海工厂整车出口欧洲
如何使用ftp命令连接远程ftp服务器
英特尔芯片有一个不可修复的安全漏洞
NIST的研究人员开发出一种用量子力学生成随机数字的方法
剖析!Redis事务实现原理
调谐LINUX网络性能之调试工具篇
白度仪的操作详解,它的作用是什么
在FPGA开发中尽量避免全局复位的使用?(3)
变频器开关电源维修
国产直流马达驱动芯片SS6216的功能参数以及应用
SmarTech发布了最新版本的间接金属3D打印报告
微软宣布Xbox系列的新Shock Blue控制器
什么是人机界面,它跟触摸屏的区别是什么
NVIDIA RTX GPU 助力宝德打造先进工业设计解决方案,推动数字化转型与升级
工信部下架37款侵犯用户权益的APP
24V闪光器电路图
abb变频器显示故障1过流怎么维修
中国联通八大5G行业应用赋能浙江产业转型升级
爆华为要发布比mate9强悍的人工智能手机 黑科技还是噱头?