ACID、MVCC、隔离级别

一、事务的ACID:

1、Atomic:原子性

多条SQL执行,要么一起成功,要么一起失败,执行状态保持一致。

2、Consistency:一致性

一组SQL执行之前,数据必须是准确的,执行之后,数据也必须是准确的。
必须符合逻辑计算。

3、Isolation:隔离性

多个事务在执行的时候不能互相干扰。

4、Durability:持久性

事务成功之后,对数据的修改是永久有效的。

二、事务隔离级别

1、读未提交--脏读,Read Uncommitted:

事务A修改的数据还没提交的时候,就被事务B给读到了,也就是脏读。

2、读已提交--不可重复读,Read Committed:

事务A先查询,然后事务B修改这条数据并且提交了,此时事务A再次查询数据不一样,所以是读已提交。
特指一个事务内对一个数据两次读,可能会读到不一样的值。

3、可重复读--幻读,Read Repeatable:

事务A在执行过程中,查询的这行数据肯定不会发生变化。
此时事务B插入一条数据,事务A本来查询到1条,现在突然看到两条,好像出现幻觉一样。
特指的是多次查询读到的行数不同。
MySQL默认事务隔离级别就是可重复读。

4、串行化:Seriaizable

如果要解决幻读,就需要使用串行化级别的隔离级别,所有事务都串行起来,不允许多个事务并行操作。

5、不可重复读和幻读的区别:

不可重复读针对的是修改,而幻读对应的是数据被删除或者新增。

image

三、MySQL默认事务隔离级别:

默认可重复读,可以避免脏读和不可重复读,但是可能出现幻读,但是MySQL同样可以避免幻读。

四、MySQL如何实现可重复读?

MySQL是通过MVCC机制来实现的,multi-version concurrency control。

innodb存储引擎,会在每行数据的最后加两个隐藏列,保存行的事务id和当前操作行的事务id,事务id是mysql自己维护的自增的,全局唯一。

id name 创建事务id 删除事务id
1 Sam 120 122
2 Jason 119 122
2 James 122 null

删除对应的事务id,要么没有,那么肯定比当前事务id大(当前开启事务之后才会删除)。

查询一行数据,创建事务id <= 当前事务id <= 删除事务id,满足上面两个条件的数据才会被查出来。

1、如果事务id = 121的查询id = 1的这行数据,是可以查到的。

2、事务id = 122把id = 1的数据删除。

3、事务id = 121查询id = 1肯定还是可以查到的。

4、事务id = 122将id = 2的name从Jason修改成James,实际上是创建一个新的数据,id不变,创建事务id为122。

5、事务id = 121 查询id = 2的那行数据,name还是Jason的,因为小于122。

更新操作:

事务执行期间,别的事务更新了一条数据呢?

在innodb中,更新是插入了一行记录,然后将新插入的记录的创建事务ID设置为新的事务的id,同时将这条记录之前的那个版本的删除事务ID设置为新的事务的id。

posted @ 2022-01-09 09:27  Diamond-Shine  阅读(136)  评论(0编辑  收藏  举报