前言
现如今JAVA开发工程师的数量越来越多,但大多数工程师平时做的工作都是简单的CRUD,当你一直处于这种舒适的环境中不追求进步的时候,如果哪一天你突然想要改变环境,换个工作,去与面试官当面聊技术的时候,你会发现自己什么都不会!
可能我们经常会被面试官问到:“你懂事务的ACID吗?”
你回答:“ACID不就是原子性、一致性、隔离性和持久性嘛,这有什么好说的。”
当你这么回答的时候,面试官微微一笑,又问到:“说的不错,那你能具体解释一下吗?”
你支支吾吾半天也没有说的特别清楚。
面试官有些不耐烦:“好了,我知道了,那你能和我说说事务的隔离级别吗?”
你突然发现自己说不出来什么,想了想,还是回去准备准备再面试吧。
小伙伴们可以思考一下,如果是你,可以很好的回答这个问题吗?如果不确定,就与王子一起深入的研究一下吧,绝对让你印象深刻。
事务的ACID
假设现在面试官让我们说一说什么是事务的ACID,我们该怎么回答呢?
首先ACID指的是原子性、一致性、隔离性和持久性。
A就是Atomic,原子性说白了就是一堆sql,要么一起执行成功,要么就都不执行,不存在其中一条执行成功的情况。
C就是Consistency,一致性是针对数据来讲的,可以理解成sql执行之前和执行之后的数据必须是准确的,不能有误差。
I就是Isolation,隔离性,就是说两个事务之间互不干扰。
D就是Durability,持久性,事务执行成功了,当然要保证修改后的数据有效了,所以要把数据保存起来。
面试官听了我们的讲解,觉得说的还不错,接着就来让我们再说一下事务的隔离级别。
事务的隔离级别
事务的隔离级别同样有四个,分别是:读未提交、读已提交(不可重复读)、可重复读、串行化。
读未提交:这个很好理解,就是说某个事务修改了一条数据,还没有提交的时候,其他事务就能读取到修改后的数据,术语上也被称为脏读;
读已提交:字面意思,就是事务修改了数据并提交之后,其他事务才能查询到修改后的数据。那为什么它又叫不可重复读呢?因为A事务修改数据提交之后,其他事务是可以直接读取到的,也就是说事务B刚开始读取的数据是1,执行过程中数据被事务A修改成了2,这个时候事务B再读取的时候获取到的是2而不是1,也就是说重复读取数据可能出现数据的不一致。
可重复读:理解了不可重复读,可重复读就很容易理解了,就是说一个事务重复读取同一个数据可以保证读取到的值与最开始读取到的值是一致的。
串行化:串行化针对的是数据的插入,比如说一个事务批量修改某个字段的值为2,但同时另一个事务在执行插入操作,插入的这个字段的值是1,这就导致了最终结果有一行数据这个字段的值是错误的,这种情况术语上被称为幻读。而解决幻读的方法就是串行化了,串行化后事务只能串行运行,不能并行操作。
面试官听了我们这样的解释之后,毫不掩饰的对我们表示了认可,但我们发现他还在思考怎么提问题。
于是我们先下手为强,准备抛出一个大招,向面试官提出“其实我对可重复读在Mysql中是如何实现的比较感兴趣,所以我研究了一下这一部分,也跟您聊聊吧”。
MySQL是如何实现可重复读的
我们知道Mysql数据库默认的隔离级别就是可重复读。
MySql的内部其实是通过MVCC机制来实现可重复读的,MVCC的意思是多版本并发控制。
Mysql的Innodb引擎会在每行数据的最后增加两个隐藏列,一个是行的创建时间,一个是行的删除时间,但这两个列中保存的其实不是时间,而是事务id,事务id是自增且唯一的。
那么假设当前数据的创建事务id为1,删除事务id为3,如下:
那么如果正在执行的事务id为2,来查询这条数据是可以查得到的,因为当前执行的事务会查询事务id=2的数据快照,所以无论后续事务对这条数据做什么操作,都不影响事务id为2的事务对这条数据的查询。
这就是MVCC机制的实现方式。
面试官听完你的这段回答之后,眼睛一下子亮了起来,立马让你明天来上班吧。
总结
今天王子想和大家讨论的问题到这里就结束了,没有什么图片的演示,也没有什么代码的展示。
主要是以模拟面试现场的方式与大家分享了ACID与隔离级别的知识,希望可以让小伙伴们印象深刻。
如果有什么问题也欢迎联系我,让我们共同探讨。