专栏首页moon聊技术redis┃面试官问我redis事务和mysql事务的区别,我。。。。。

redis┃面试官问我redis事务和mysql事务的区别,我。。。。。

1

前言

面试官:我看你简历上写了熟悉redis,看来工作中用的很多吧?

我:是的,我们项目中经常用到redis(来,随便问,看我分分钟秒杀你)

面试官:那你给我说说redis的事务和mysql的事务有什么区别吧

我:额。。。事务还有区别????

面试官:比如说redis的事务是不支持原子性和持久性的,包括他们的实现原理等方面也是有很大区别的。

我:学到了。。。。。。

2

正文

事务的四大特性

ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

原子性(Atomicity)

说的是一个事物内所有操作就是最小的一个操作单元,要么全部成功,要么全部失败。这是最基本的特性,保证了因为一些其他因素导致数据库异常,或者宕机。

一致性(Consistency)

一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。

一致性有下面特点:

  • 如果一个操作触发辅助操作(级联,触发器),这些也必须成功,否则交易失败。
  • 如果系统是由多个节点组成,一致性规定所有的变化必须传播到所有节点(多主复制)。如果从站节点是异步更新,那么我们打破一致性规则,系统成为“最终一致性”。
  • 一个事务是数据状态的切换,因此,如果事务是并发多个,系统也必须如同串行事务一样操作。

在现实中,事务系统遭遇并发请求时,这种串行化是有成本的, Amdahl法则描述如下:它是描述序列串行执行和并发之间的关系。

“一个程序在并行计算情况下使用多个处理器所能提升的速度是由这个程序中串行执行部分的时间决定的。”

大多数数据库管理系统选择(默认情况下)是放宽一致性,以达到更好的并发性。

隔离性

事物的隔离性,基于原子性和一致性,因为事物是原子化,量子化的,所以,事物可以有多个原子包的形式并发执行,但是,每个事物互不干扰。

但是,由于多个事物可能操作同一个资源,不同的事物为了保证隔离性,会有很多锁方案,当然这是数据库的实现,他们怎么实现的,我们不必深究。

持久性

持久性,当一个事物提交之后,数据库状态永远的发生了改变,即这个事物只要提交了,哪怕提交后宕机,他也确确实实的提交了,不会出现因为刚刚宕机了而让提交不生效,是要事物提交,他就像洗不掉的纹身,永远的固化了,除非你毁了硬盘。

事务命令

mysql:

Begin:显式的开启一个事务

Commit:提交事务,将对数据库进行的所有的修改变成永久性

Rollback:结束用户的事务,并撤销现在正在进行的未提交的修改

redis:

Multi:标记事务的开始

Exec:执行事务的commands队列

Discard:结束事务,并清除commands队列

默认状态

mysql:

mysql会默认开启一个事务,且缺省设置是自动提交,即每成功执行sql,一个事务就会马上commit,所以不能rollback,

redis:

redis默认不会开启事务,即command会立即执行,而不会排队,并不支持rollback

使用方式

mysql(包含两种方式):

用Begin、Rollback、commit显式开启并控制一个 新的 Transaction

执行命令 set autocommit=0,用来禁止当前会话自动commit,控制 默认开启的事务

redis:

用multi、exec、discard,显式开启并控制一个Transaction。

(注意:这里没有强调 “新的” ,因为默认是不会开启事务的)。

实现原理

mysql:

mysql实现事务,是基于undo/redo日志

undo记录修改前状态,rollback基于undo日志实现

redo记录修改后的状态,commit基于redo日志实现

既然是基于redo日志实现记录修改后的状态,那么大家应该也知道,redo日志是innodb专有的,所以innodb会支持事务

在mysql中无论是否开启事务,sql都会被立即执行并返回执行结果,只是事务开启执行后的状态只是记录在redo日志,执行commit之后,数据才会被写入磁盘

(以上内容后面我会详细在mysql篇给大家讲到,大家可以先简单了解下)

int insertSelective = serviceOrderMapper.insertSelective(s);

所以,上述代码,insertSelective 将会被立即赋值(无论是否开启事务,只是结果或未被写入磁盘):

insertSelective = 受影响的行数;

redis:

redis实现事务,是基于commands队列

如果没有开启事务,command将会被立即执行并返回执行结果,并且直接写入磁盘

如果事务开启,command不会被立即执行,而是排入队列,并返回排队状态(具体依赖于客户端(例如:spring-data-redis)自身实现)。

调用exec才会执行commands队列

boolean a = redisTemplate.opsForZSet().add("generalService",orderId,System.currentTimeMillis())boolean a = redisTemplate.opsForZSet().add("generalService",orderId,System.currentTimeMillis())

以上代码如果没有开启事务,操作被立即执行,a将会被立即赋值(true/false)

如果开启事务,操作不会被立即执行,将会返回null值,而a的类型是boolean,所以将会抛出异常:

java.lang.NullPointerException   空指针异常

Redis事务不支持Rollback(重点)

事实上Redis命令在事务执行时可能会失败,但仍会继续执行剩余命令而不是Rollback(事务回滚)。如果你使用过关系数据库,这种情况可能会让你感到很奇怪。然而针对这种情况具备很好的解释:

  • Redis命令可能会执行失败,仅仅是由于错误的语法被调用(命令排队时检测不出来的错误),或者使用错误的数据类 型操作某个Key: 这意味着,实际上失败的命令都是编程错误造成的,都是开发中能够被检测出来的,生产环境中不应该存在。
  • 由于不必支持Rollback,Redis内部简洁并且更加高效。

redis 事务中的错误

事务期间,可能会遇到两种命令错误:

  • 在调用EXEC命令之前出现错误(COMMAND排队失败)。
  • 例如,命令可能存在语法错误(参数数量错误,错误的命令名称...);
  • 或者可能存在某些关键条件,如内存不足的情况(如果服务器使用maxmemory指令做了内存限制)。

客户端会在EXEC调用之前检测第一种错误。 通过检查排队命令的状态回复(***注意:这里是指排队状态回复,而不是执行结果***),如果命令使用QUEUED进行响应,则它已正确排队,否则Redis将返回错误。如果排队命令时发生错误,大多数客户端将中止该事务并清除命令队列。然而:

  • Redis 2.6.5之前,这种情况下,在EXEC命令调用后,客户端会执行命令的子集(成功排队的命令)而忽略之前的错误。
  • Redis 2.6.5开始,服务端会记住在累积命令期间发生的错误,当EXEC命令调用时,将拒绝执行事务,并返回这些错误,同时自动清除命令队列
  • 示例如下:
>MULTI
+OK
>INCR a b c
-ERR wrong number of arguments for 'incr' command

这是由于INCR命令的语法错误,将在调用EXEC之前被检测出来,并终止事务(version2.6.5+)。

  • 在调用EXEC命令之后出现错误。
  • 例如,使用错误的值对某个key执行操作(如针对String值调用List操作)

EXEC命令执行之后发生的错误并不会被特殊对待即使事务中的某些命令执行失败,其他命令仍会被正常执行

  • 示例如下:
>MULTI
+OK
>SET a 3
+QUEUED
>LPOP a
+QUEUED
>EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind of value>
  • EXEC返回一个包含两个元素的字符串数组,一个元素是OK,另一个是-ERR……
  • 能否将错误合理的反馈给用户这取决于客户端library(如:Spring-data-redis.redisTemplate)的自身实现。
  • 需要注意的是,即使命令失败,队列中的所有其他命令也会被处理----Redis不会停止命令的处理。

3

结语

今天moon给大家讲了redis的事务和mysql 的事务到底有什么区别,看完这篇文章大家也应该大致明白了

redis和mysql 的事务在默认状态,使用方式,实现原理等方面都是有很大区别的

mysql的事务完美的支持了事务的四大特性,而redis事务只保证了其中的一致性和隔离性,不满足原子性和持久性

当面试官问到你的时候想必你也能够对答如流了吧。

redis系列的文章已经更新的差不多了,下一篇我们来聊聊在如何使用redis做分布式锁。

记得点赞

本文分享自微信公众号 - moon聊技术(onetraveller_llxz),作者:moon聊技术

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 京东面试官问我:“聊聊MySql事务,MVCC?”

    多个事务互相影响,并没有隔离好,就是我们刚才提到的事务的四大特性中的 隔离性(Isolation) 出现了问题 事务的隔离级别并没有设置好,下面我们来看下事务究...

    java小杰要加油
  • 【分布式事务】面试官问我:如何恢复MySQL中的XA事务?

    作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了...

    冰河
  • 【分布式事务】面试官问我:MySQL中的XA事务崩溃了如何恢复??

    作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了...

    冰河
  • 搞清楚这 10 几个后端面试问题,工作稳了!

    面试过程是一个由浅入深的过程,面试官先给求职者抛出一个相对简单的问题,然后通过一环套一环的追问深入考察求职者对知识点的理解掌握程度。

    JAVA日知录
  • 【MySQL】我这样分析MySQL中的事务,面试官对我刮目相看!!

    作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了...

    冰河
  • 分析阿里/京东/网易Java岗面试,总结出70道高频必问题(含解析)

    用户5546570
  • 面试官:你说对MySQL事务很熟?那我问你10个问题

    学习关系型数据库MySQL是很好的切入点,大部分人学习和工作中用惯了CRUD,对面试官刨根问底的灵魂拷问你还能对答如流吗?我们有必要了解一些更深层次的数据库基础...

    Guide哥
  • 2019 腾讯java面试 (含面试题解析)

    本人3年开发经验、18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴、今日头条、滴滴等公司offer,岗位是Java后端开发,最终选择去了阿里巴巴。

    木有bug
  • 2019BATJ面试题详解:MyBatis+MySQL+Spring+Redis+多线程

    如何通过HibernateDaoSupport将Spring和Hibernate结合起来?

    美的让人心动
  • 2019BATJ面试题汇总详解:MyBatis+MySQL+Spring+Redis+多线程

    如何通过HibernateDaoSupport将Spring和Hibernate结合起来?

    欧阳愠斐
  • 又陷入知识盲区了,面试被问Redis事务,我差点脸都“绿”了

    前几天有读者说自己面试被问到Redis的事务,虽然不常用,但是面试竟然被问到,平时自己没有注意Redis的事务这一块,面试的时候被问到非常不好受。

    Java程序猿阿谷
  • 2019BATJ面试题汇总详解:MyBatis+MySQL+Spring+Redis+多线程

    如何通过HibernateDaoSupport将Spring和Hibernate结合起来?

    慕容千语
  • 社招一年半面经分享(含阿里美团头条京东滴滴)

    最近一段时间面试了几家互联网公司,陆续通过了阿里、头条、美团,滴滴,京东的面试,基本上面试的公司都通过了,所以在这里想分享一些自己面试的经验给大家,希望能帮助大...

    捡田螺的小男孩
  • 背完这套Java面试八股文,自动解锁面试牛逼症被动技能

    国内的互联网面试,恐怕是现存的、最接近科举考试的制度。很多人对八股文都嗤之以鼻,认为无法衡量出一个程序员的真是水平。还有一部分人则是深恶痛绝,因为实在太难背了。

    北游
  • 2020预备春招BAT面试题汇总:MyBatis +微服务+多线程+Spring+分布式

    本文收集整理了各大厂常见面试题N道,你想要的这里都有内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcac...

    架构师修行之路
  • 985渣硕的春招总结(三次面试三个Offer)

    2020届 软件工程专业 本硕都是武大 又菜又怂,春招就没投几家公司,看着牛油们个个BAT,又悔又恨

    牛客网
  • Java程序员秋招面经大合集(BAT美团网易小米华为中兴等)

    1, 自我介绍 2, 项目介绍 3, 项目架构 4, 项目难点 5, Synchronize关键字为什么jdk1.5后效率提高了 6, 线...

    desperate633
  • Java程序员“硬闯”阿里之路,已收获offer(附超详细面经)

    本人3年开发经验、18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴、今日头条、滴滴等公司offer,岗位是Java后端开发,最终选择去了阿里巴巴。

    秃顶的Java程序员
  • 如果没准备这些面试题,找工作还是先缓缓吧

    Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring B...

    JAVA葵花宝典

扫码关注云+社区

领取腾讯云代金券