目录
一、MySQL的事务隔离级别是如何实现的
1、READ UNCOMMITTED
它是性能最好、也是最野蛮的方式,因为它不加锁,所以根本谈不上隔离效果,可以理解为没有隔离。
2、SERIALIZABLE
读的时候加共享锁,其它事务可以并发读,但是不能写。写的时候加排它锁,其它事务不能并发写也不能并发读。
3、REPEATABLE READ & READ COMMITTED
为了解决不可重复读,MySQL采用了MVVC(多版本并发控制)的方式。
相关内容参考第三、四部分。
二、事务是否可以嵌套
可以。
因为嵌套事务也是众多事务分类中的一种,它是一个层次结构框架。有一个顶层事务控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务,它控制着每一个局部的变换。
需要注意的是,MySQL数据库不支持嵌套事务。
三、简述如何实现可重复读
为了实现可重复读,MySQL采用了MVVC(多版本并发控制)的方式。
我们在数据库表中看到的一行记录可能实际上有多个版本,每个版本的记录除了有数据本身外,还要有一个表示版本的字段,记作row trx_id,而这个字段就是使其产生的事务的id,事务ID记为transaction id,它在事务开始的时候向事务系统申请,按时间先后顺序递增。
如下图,一行记录现在有3个版本,每一个版本都记录着使其产生的事务ID,比如事务A的transaction id是100,那么版本1的row trx_id就是100,同理版本2和版本3。
可重复读是在事务开始的时候生成一个当前事务全局性的快照。对于一个快照来说,它能够读到哪些版本数据,要遵循以下规则:
1、当前事务内的更新,可以读到;
2、版本未提交,不能读到;
3、版本已提交,但是却在快照创建后提交的,不能读到;
4、版本已提交,且是在快照创建前提交的,可以读到。
四、简述如何解决幻读问题
MySQL 已经在可重复读隔离级别下解决了幻读的问题,用的是间隙锁。MySQL 把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁。
假设现在表中有两条记录,并且age字段已经添加了索引,两条记录age的值分别为10和30。此时,在数据库中会为索引维护一套B+Tree,用来快速定位行记录。B+索引树是有序的,所以会把这张表的索引分割成几个区间。如图所示,分成了3个区间,在这3个区间是可以加间隙锁的。
之后,用下面的两个事务演示一下加锁的过程。
在事务A提交之前,事务B的插入操作只能等待,这就是间隙锁起的作用。当事务A执行update user set name='风筝2号’ where age = 10;的时候,由于条件where age = 10,数据库不仅在age = 10的行上添加了行锁,而且在这条记录的两边,也就是(负无穷,10]、(10,30]这两个区间加了间隙锁,从而导致事务B插入操作无法完成,只能等待事务A提交。不仅插入age = 10的记录需要等待事务A提交,age<10、10<age<30的记录页无法完成,而大于等于30的记录则不受影响,这足以解决幻读问题。
这是有索引的情况,如果age不是索引列,那么数据库会为整个表加上间隙锁。所以,如果是没有索引的话,不管是age是否大于等于30,都要等待事务A提交才可以成功插入。
五、MySQL事务如何回滚
在MySQL默认的配置下,事务都是自动提交和回滚的。当显示地开启一个事务时,可以使用ROLLBACK 语句进行回滚。该语句有两种用法:
1、ROLLBACK:要使用这个语句的最简形式,只需发出ROLLBACK。同样地,也可以写为ROLLBACK WORK,但是二者几乎是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改。
2、ROLLBACK TO [SAVEPOINT] identifier :这个语句与SAVEPOINT命令一起使用。可以把事务回滚到标记点,而不回滚在此标记点之前的任何工作。
标签:10,事务,提交,age,版本,MySQL,数据库 From: https://blog.csdn.net/L_peanut/article/details/140322022