[原]redis&mysql的事务为什么区别会这么大

本文主要是讨论redis的事务和传统事务(mysql)在设计上的区别和背后的设计决策的借鉴意义

可能大多数人都会觉得这个不是很正常,两个不一样的数据库,有各自的优势和不同的应用场景,事务处理上有点区别有什么奇怪的,这。。。确实没错,but....了解采取这种决策方式背后的意图和对相同实现方式不同场景下的设计决策对比的思考,对我们现实的项目设计中采取哪些方案是很有帮助的。

先来看看redis和mysql对于事务处理涉及到的相关命令:


image.png

当然mysql在事务回滚上还有更多的玩法,例如:SAVEPOINT

从这里你至少会发现:redis没有提供和回滚有关的命令,或者你会觉得还能接受,至少如果在事务执行过程中出现问题了,redis整个的事务还能回滚,然而,实际并不是这样的,redis的事务中,就算其中一个执行失败了,后面的事务还是会继续进行!并不是你理想中的,整个事务就失败了。

来看看redis的官方文档是如何定义redis的原子性:

Either all of the commands or none are processed, so a Redis transaction is also atomic.
意思是:事务中的命令要么全部被执行,要么全部都不执行,所以redis的事务也是原子性

所以,你会看到文档中强调:

It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.

而mysql事务的原子性的定义:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

到这里,我们整理一下redis和mysql的事务的区别:
1,没有提供回滚相关的命令,无法像mysql一样提供任意时刻任意点的回滚
2,事务执行过程中有某条/某些命令执行失败了, 事务队列中的其他命令仍然会继续执行 —— Redis 不会停止和回滚执行事务中的命令。

所以从这两点上看出,redis必须保证每条命令成功执行,否则这个事务就不符合事务的标准:1,无法保证原子性 2,无法保证一致性

通过redis对事务介绍的文档中看出设计者对于redis事务设计的两个特征:
1,不考虑事务执行命令时外界上下文逻辑
2,基于redis单线程模型实现的事务处理

不考虑事务执行命令的外界上下文逻辑

redis执行事务的过程:MULTI 命令开启一个事务后, 客户端向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC命令被调用时, 队列中的命令才会被执行。

在这里,你可以发现redis触发事务的执行时是脱离外部业务逻辑的上下文关系的,这一点和mysql完全不同:mysql的每个语句是可以充分的结合到整个业务过程中,也就是事务开启时,外界上下文的触发的每一步操作都是同步执行的, 会对访问同一资源的其他事务造成影响,这也是mysql事务应用广泛之处,并通过多版本控制实现不同隔离级别状态的任意的回滚。

而redis这种简单粗暴的事务方式的带来的直接好处是:
1,摆脱的来自于外界的阻塞,阻塞这一点对于要求高性能的redis来说是绝对不可接受的,而在mysql上,你会时不时看到长事务导致了整个系统的性能问题。
2,剥离了外部不可控的因素,redis事务就只是命令的集合,所以redis设计者发现传统事务都支持的回滚(roll back)这种操作完全是多余的:

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选择了性能,而放弃了可能因为外部人为问题而导致数据不一致问题(mysql事务刚好相反)。

基于redis单线程模型实现的事务处理

可能你会疑问上面redis会有隔离级别而导致性能问题?
redis确实没有,因为这些为redis的高性能让步,redis可以说是天然的串行化的隔离级别,redis事务是保证在执行事务中的一连串操作时不受其他客户端的命令打断,达到串行执行的目的。配合上 WATCH就可以实现和mysql的串行化隔离级别的效果
而从这一执行效果可以看到,redis还是基于现有的单线程模型来实现事务,这更能佐证一点:设计者为了保证高性能,宁愿放弃一些外部因素导致事务的数据不一致问题,虽然redis可以通过多线程来实现来引入事务回滚并能确保事务过程中的redis服务的可用性。

总结

到这里,我们知道了,redis的事务只要正确执行(没有人为失误),也是同样满足传统事务的四大特性(ACID),也了解了redis事务的使用场景以及做出这些决策背后的原因,可见:
数据库系统事务设计中,保证一个事务完整执行,原本数据一致性应该是首要位置,因此,系统设计中必然要考虑到更多的异常的不可控的情况和相应的处理机制,从而保证系统自身的数据安全, 而在redis中,我们看到了另外一种可能:为了保证redis的高性能而在设计决策上所做的妥协和调整, 虽然保证严格的一致性似乎对于严谨的事务设计方案来说会更让人接受,但这对于redis来说,其实仅仅只是一个局部的功能,从整个系统的角度上,高性能和效率才是redis的初衷,从而也理解redis事务的特殊之处和其应用场景。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345