MySQL知识点复习 - 事务篇
由于在线上真没用过MySQL,一般用的都是PostgreSQL、Oracle和Sql Server,完美对八股文的神MySql没有一丝线上经验,故来小卷一手。
事务的特性是什么?
- 原子性:执行的任务要么是一次完成要么就是全部是失败,都会被回滚到事务前的状态
- 一致性:事务在操作前和操作后无论干了什么数据都是一致的
- 隔离性:防止多个事务并发的时候由于交叉执行而导致数据不一致
- 持久性:事务处理结束后对于数据的修改是永久持久性的
怎么实现的?
在MySQL的InnoDB引擎技术中,持久性是通过 redo log
(重做日志)来保证的,原子性通过 undo log
(回滚日志),隔离性通过MVCC(多版本并发控制)或是🔒机制来实现的。一致性则是通过上述是三个特性来完成的。
事务的隔离级别有哪些?
插播一条知识点:
在同时处理多个并发的时候,就会容易出现三种情况,
- 脏读:如果有一个事务读取到还没有提交的事务的时候,也就是脏读(因为这个事务可能会撤回)
- 不可重复读:简单的理解就是连续读的数据都不一致。就是当有其中一个事务,比如说是事务A,他自己search了一次数据,但是并没有什么操作,然后事务B,操作了提交了事务,修改了这个数据,当事务A再search一次这个数据的时候,发现数据已经不一致了,这个就是不可重复读。
- 幻读:(记录数量)字面意思感觉产生了幻觉。比如事务A在进行条件查询,根据这个条件筛选出来的数据还是正常的,但是同时在事务B也在进行查询,这个时候大家都还是正常的,就在这个时候,事务A开始偷偷对这个数据进行了操作,然后事务B再进行一次查询的时候,发现怎么数据多了一条?这个就是幻读。(这听起来怎么跟不可重复读差不多?)但是,其实这个只有在一个事务内多次进行条件筛选条件时候出现的问题,才会叫做幻读。(而不可重复读只是单纯的多次读取同一个数据,这就是差别。)
- 读未提交:在事务还没有提交的时候,大家就能看到它已经修改了什么内容
这里就可能会出现脏读、不可重复读和幻读的现象,在提交之前如果挂了是不是就得全部回滚了
- 读提交:需要等所有的步骤完成事务提交,大家才能看到最终的修改内容
这种就不会出现脏读的情况,那么是不是可能也会出现不可重复读和幻读的现象呢
- 可重复读:指在事务的执行过程时到事务开始的时候的数据都是一致的。(MySQL默认的隔离级别)
这种情况会有可能出现幻读的情况
- 串行化:会对当前提交的事务先加上读写锁,当有多个事务进来,造成了读写冲突,后面来的事务就必须等前面的事务执行完毕了之后才能继续执行。
加锁导致的多半只是性能差,但是安全性肯定是高的
研究一下什么是MVCC
MVCC允许多个事务同时读取同一条数据,而不会彼此阻塞,每个事务看到的版本都是事务开始时的数据版本,也就是说,每个人看到的数据,都是自己在操作时开始看到的数据,换个意义来说这就是非阻塞的读操作。
Read View:简单的理解他就是一个数据快照,复杂的理解他就是一个类似于视图的东西吗?(这是我的理解),Read view里面会有几个字段,随便捞几个出来分析一下:
-
creator_trx_id:创建这个read view事务的事务id
-
m_ids:在创建read view的时候,有一些事务启动了但是却还没有提交的事务的id列表,这个是列表,看字段名也是ids不是id。
-
min_trx_id:这个是m_ids的最小值
-
max_trx_id:创建read view的时候数据库准备给下一个事务准备的id值
插播小知识
在InnoDB引擎中,在每个表中都会有两个隐藏的字段
- trx_id:事务的id会存放在这个字段中
- roll_pointer:指针列,指向旧版本的记录
创建Read View的时候,可以将trx_id划分为下面的这个版本链,以这种版本链的形式生成的就叫做MVCC多版本并发控制。
已提交事务 -> (生成min_trx_id最小的m_ids值)-> 已启动但未提交的事务 -> (生成max_trx_id最大的m__ids值)-> 还没有开始的事务
还有那么几种情况需要分析一下
- 当的trx_id小于Read view的最小值的时候,证明这个事务是之前的事务创建的read view,是已经提交了的事务,所以这条数据的最终版本我们是可以看到的。
- 当trx_id大于或等于read view的最小值的时候,证明这个事务是在创建read view后才生成的事务,所以这条数据的最终版本我们是还不可以看到的。
- 如果trx_id在ids的最小值和最大值之间的时候,就需要判断这个trx_id是不是在m_ids这个列表之中了
- 如果在列表中,证明这个还是一个未提交的事务,所以是看不到最终的版本
- 如果不在列表中,证明这个事务已经被提交了,可以看到最终的版本。
wtf ?? 好复杂人被搞晕了