分布式事务(二)事务基础ACID隔离级别MVCC Diamond

一、事务的ACID:

1、Atomic:原子性

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

2、Consistency:一致性

这个是针对数据一致性来说的。
就是一组SQL执行之前,数据必须是准确的,执行之后,数据也必须是准确的。
总不能,执行了SQL,结果SQL对应的数据压根没变。

3、Isolation:隔离性

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

4、Durability:持久性

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

二、事务隔离级别

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

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

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

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

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

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

4、串行化:Seriaizable

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

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

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

image

MySQL默认事务隔离级别:

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

就是说每个事务都会开启一个自己要操作的某个数据的快照,事务期间,读到的都是这个数据的快照罢了,对一个数据的多次读都是一样的。

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

MySQL是通过MVCC机制来实现的,就是多版本并发控制,multi-version concurrency control。

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

id name 创建事务id 删除事务id
1 Sam 120 122
2 Jason 119 null
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。

原文地址:https://www.cnblogs.com/huigelaile/p/15780339.html