0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

剖析!Redis事务实现原理

张康康 2019-07-29 18:27 次阅读

作者 | Video++极链科后端Team刘聪

整理 | 包包

所谓事务(Transaction) ,是指作为单个逻辑工作单元执行的一系列操作。事务必须满足ACID原则(原子性、一致性、隔离性和持久性)。简单来说事务其实就是打包一组操作(或者命令)作为一个整体,在事务处理时将顺序执行这些操作,并返回结果,如果其中任何一个环节出错,所有的操作将被回滚。

在Redis中实现事务主要依靠以下几个命令来实现:

剖析!Redis事务实现原理


Redis事务从开始到结束通常会通过三个阶段:

1.事务开始

2.命令入队

3.事务执行

以下是一个最简单的Redis事务流程:

剖析!Redis事务实现原理


第一步跟其他的关系型数据库类似,也是需要开启一个事务,在Redis中的命令如下:

剖析!Redis事务实现原理


Redis中使用MULTI命令标记事务的开始,可以理解为在传统关系型数据库中的BEGIN TRANCATION语句,Redis将执行该命令的客户端从非事务状态切换成事务状态,这一切换是通过在客户端状态的flags属性中打开REDIS_MULTI标识完成, 我们看下Redis中对应部分的源码实现:

剖析!Redis事务实现原理


在打开事务标识的客户端里,这些命令都会被暂存到一个命令队列里,不会因为用户会的输入而立即执行。

第二步就是执行事务内路基,即真正的业务逻辑:

剖析!Redis事务实现原理


最后一个阶段是提交事务(或者回滚事务):

剖析!Redis事务实现原理


这两个命令可被视为等同于关系型数据库中的COMMIT/ROLLBACK语句。

这里需要注意的是,在客户端打开了事务标识后,只有命令:EXEC,DISCARD,WATCH,MULTI命令会被立即执行,其它命令服务器不会立即执行,而是将这些命令放入到一个事务队列里面,然后向客户端返回一个QUEUED回复 ;Redis客户端有自己的事务状态,这个状态保存在客户端状态mstate属性中,mstate的结构体类型是multiState,我们看下multiState的定义:

剖析!Redis事务实现原理


我们再看下结构体类型multiCmd的结构:

剖析!Redis事务实现原理


事务队列以先进先出的保存方法,较先入队的命令会被放到数组的前面,而较后入队的命令则会被放到数组的后面。

当开启事务标识的客户端发送EXEC命令的时候,服务器就会执行,客户端对应的事务队列里的命令,我们来看下EXEC 的实现细节:

剖析!Redis事务实现原理


最后我们再回顾一下事务本身的特性, 在传统关系型数据库中的事务必须依靠ACID来保证事务的可靠性和安全性,在Redis中事务总是具有一致性(Consistency)和隔离性(Isolation),并且当Redis运行在某种特定的持久化模式下,事务也具有耐久性(Durability); 但是并不总是能够保证原子性(Atomicity),在正常状态下一个事务的所有命令是能按照原子性的原则执行的,但是执行的中途遇到错误,不会回滚,而是继续执行后续命令, 如下:

剖析!Redis事务实现原理


如果在set k2 v2处失败,set k1已成功不会回滚,set k3还会继续执行;Redis的事务和传统的关系型数据库事务的最大区别在于,Redis不支持事务的回滚机制,即使事务队列中的某个命令在执行期间出现错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止,我们看下面的例子:

剖析!Redis事务实现原理


Redis的作者在事务功能的文档中解释说,不支持事务回滚是因为这种复杂的功能和Redis追求的简单高效的设计主旨不符合,并且他认为,Redis事务的执行时,错误通常都是编程错误造成的,这种错误通常只会出现在开发环境中,而很少会在实际的生产环境中出现,所以他认为没有必要为Redis开发事务回滚功能。所以我们在讨论Redis事务回滚的时候,一定要区分命令发生错误的时候。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏

    评论

    相关推荐

    Redis可以实现消息中间件MQ的功能

    是一种通信模式:发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接收消息,可以实现进程间的消息传递   Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息
    的头像 发表于 01-25 14:48 459次阅读
    <b class='flag-5'>Redis</b>可以<b class='flag-5'>实现</b>消息中间件MQ的功能

    redis数据结构的底层实现

    Redis是一种内存键值数据库,常用于缓存、消息队列、实时数据分析等场景。它的高性能得益于其精心设计的数据结构和底层实现。本文将详细介绍Redis常用的数据结构和它们的底层实现
    的头像 发表于 12-05 10:14 395次阅读

    redis持久化机制和如何实现持久化

    Redis是一款高性能的非关系型数据库,其持久化机制是保证数据在重启后仍能够保存的关键。Redis提供了两种方式来实现持久化:RDB(Redis DataBase)和AOF(Appen
    的头像 发表于 12-05 10:02 320次阅读

    redis hash底层实现原理

    数据结构是如何实现的呢?本文将详细介绍Redis哈希底层的实现原理。 在Redis中,每个哈希都是由一个类似于字典(Dictionary)的结构实现
    的头像 发表于 12-04 16:27 354次阅读

    如何实现Redis分布式锁

    锁机制,下面将详细介绍如何实现Redis分布式锁。 一、引言 在分布式系统中,多个节点可能同时读写同一共享资源。如果没有实现互斥访问和同步机制,就会产生数据不一致和竞态条件等问题。解决这个问题的一种方法是使用分布式锁,在访问共享
    的头像 发表于 12-04 11:24 471次阅读

    redis锁机制原理

    Redis是一款高性能的开源内存数据库,用于存储和检索数据。在多线程或分布式环境中,需要实现并发控制来保证数据一致性和线程安全。Redis提供了一种简单而高效的锁机制,可以用来实现并发
    的头像 发表于 12-04 11:08 585次阅读

    Java redis锁怎么实现

    在Java中实现Redis锁涉及到以下几个方面:Redis的安装配置、Redis连接池的使用、Redis数据结构的选择、
    的头像 发表于 12-04 10:47 523次阅读

    Redis工具集的实现和使用

    Redis 基本上是互联网公司必备的工具了,Redis的应用场景实在太多了,但是有很多相似的功能如果每个项目都要实现一遍就显得太麻烦了,所以为了方便,我打算开发一个基于 Redis
    的头像 发表于 12-03 17:32 797次阅读
    <b class='flag-5'>Redis</b>工具集的<b class='flag-5'>实现</b>和使用

    使用Redis的有序集合实现排行榜功能和Spring Boot集成

    Redis 的有序集合(Sorted Set)是一个基于分数(score)排序的数据结构,它在 Redis 中非常重要,常用于实现排行榜、近似计数器等功能。
    的头像 发表于 11-20 10:15 415次阅读

    redis分布式锁如何实现锁等待

    Redis是一种高性能的键值存储系统,它除了提供基本的数据缓存功能外,还支持一些复杂的数据结构和功能,例如发布订阅、事务、持久化等。其中,Redis的分布式锁是其常用的功能之一,可以用于解决多个
    的头像 发表于 11-16 11:31 784次阅读

    redis分布式锁如何实现

    Redis分布式锁是一种基于Redis实现的机制,可以用于多个进程或多台服务器之间对共享资源的并发访问控制。在分布式系统中,由于多个进程或多台服务器同时访问共享资源,可能会发生数据竞争和资源冲突
    的头像 发表于 11-16 11:29 364次阅读

    Redis是什么?简述它的优缺点?

    次/s,写的速度是81000次/s。 支持数据持久化,支持AOF和RDB两种持久化方式。 支持事务Redis的所有操作都是原
    的头像 发表于 10-09 10:37 555次阅读

    Redis中的使用

    中断。只有在执行完所有命令后才会继续执行来自其他客户的消息。 Redis 中的使用 Redis 通过 multi,exec,discard,watch 实现事务功能。 multi:开始
    的头像 发表于 10-08 15:27 297次阅读
    <b class='flag-5'>Redis</b>中的使用

    redis分布式锁场景实现

    今天带大家深入剖析一下Redis分布式锁,彻底搞懂它。 场景 既然要搞懂Redis分布式锁,那肯定要有一个需要它的场景。 高并发售票问题就是一个经典案例。 搭建环境 准备redis服务
    的头像 发表于 09-25 17:09 523次阅读

    Redis的LRU与LFU算法实现

    Redis是一款基于内存的高性能NoSQL数据库,数据都缓存在内存里, 这使得Redis可以每秒轻松地处理数万的读写请求。
    的头像 发表于 07-11 09:48 554次阅读
    <b class='flag-5'>Redis</b>的LRU与LFU算法<b class='flag-5'>实现</b>