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事务回滚的时候,一定要区分命令发生错误的时候。


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

    评论

    相关推荐

    Spring事务实现原理

    这些操作。 spring事务有编程式事务和声明式事务两种实现方式。编程式事务是通过编写代码来管理事务
    的头像 发表于 11-08 10:10 746次阅读
    Spring<b class='flag-5'>事务实现</b>原理

    Redis开源版与Redis企业版,怎么选用?

    点击“蓝字”关注我们数以千计的企业和数以百万计的开发人员Redis开源版来构建应用程序。但随着用户数量、数据量和地区性的增加,成本、可扩展性、运营和可用性等问题也随之而来。Redis企业版
    的头像 发表于 04-04 08:04 976次阅读
    <b class='flag-5'>Redis</b>开源版与<b class='flag-5'>Redis</b>企业版,怎么选用?

    Redis实现分布式多规则限流的方式介绍

    市面上很多介绍 Redis 如何实现限流的,但是大部分都有一个缺点,就是只能实现单一的限流,比如 1 分钟访问 1 次或者 60 分钟访问 10 次这种,但是如果想一个接口两种规则都需要满足呢,我们的项目又是分布式项目,应该如何
    的头像 发表于 02-26 10:07 452次阅读
    <b class='flag-5'>Redis</b><b class='flag-5'>实现</b>分布式多规则限流的方式介绍

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

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

    Redis的LRU实现和应用

    在编程中,计数器是一种基本但强大的工具,用于跟踪和管理数据和资源。本文将深入探讨不同类型的计数器的应用,从Redis的LRU(最近最少使用)缓存淘汰算法的实现,到如何在内存受限的环境中有效地使用计数器,再到普通计数器的巧妙应用。
    的头像 发表于 12-15 09:24 573次阅读

    redis数据结构的底层实现

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

    redis容器内怎么查看redis日志

    redis是一款流行的开源内存数据库,常用于缓存、消息队列、任务管理等场景。在使用redis时,了解如何查看redis日志对于排查问题、监控性能和分析应用程序行为非常重要。在本文中,我们将介绍在
    的头像 发表于 12-05 10:10 3510次阅读

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

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

    redis的lru原理

    Redis是一种基于内存的键值数据库,它使用了LRU(Least Recently Used)算法来进行缓存的数据淘汰。LRU算法的核心思想是最近最少使用的数据将会在未来也不常用,因此应该优先
    的头像 发表于 12-05 09:56 607次阅读

    redis hash底层实现原理

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

    redis的淘汰策略

    Redis是一种基于内存的键值存储系统,为了充分利用内存,Redis采用了一些淘汰策略来管理内存空间。淘汰策略的作用是当内存空间不足时,选择合适的数据对象进行淘汰,释放出更多的内存空间,以供后续
    的头像 发表于 12-04 16:23 523次阅读

    如何实现Redis分布式锁

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

    java redis锁处理并发代码

    问题。 本文将详细介绍如何在Java代码中使用Redis实现并发代码的锁处理。我们将分为以下几个方面来讨论: Redis分布式锁的原理 Redis分布式锁的
    的头像 发表于 12-04 11:04 925次阅读

    Java redis锁怎么实现

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

    Redis工具集的实现和使用

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