mysql事物隔离
事物的启动时机
bagein/start transaction命令并不是一个事务的起点,在执行事务到它们之后的第一个操作innodb的语句,才是事务开启。
如果要立马启动一个事务,可以使用 start transaction with consistent snapshot 这个命令。
mysql ,两个视图概念
1.一个是view。它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建试图的语法是 create view。。。。,而它的查询方法和表一致。
2.另一个是innodb在实现 MVCC时用到的一致性读视图,即 consistent read view,用于支持RC(read committed,读提交)和 RR(Repeatable read,可重复读)隔离级别实现。
‘快照’在MVCC里的工作:
在可重复读 隔离级别。事务启动的时候就拍了快照。--对整个表进行
innodb 里面每一个事务都有一个唯一事务id,叫做 transaction id 。它是在事务开始的时候想 idnodb 的事务系统申请的,严格按照申请顺序递增。
每行数据多版本。每次事务更新都会数据都会生成一个 transaction id 作为数据版本的事务ID,记作 row rrx_id 。
同时旧的数据保留。并在新数据版本中可以直接拿到
inbodb 构造了一个数组用于保存,事务启动的瞬间所有 活跃 的事务id “活跃”指的就是,启动了但还没提交。
数组中id最小值为低水位,当前系统里面已经创建过的事务ID的最大值加1记为高水 位
1.小于低水位,数据可见
2.高于高水位 事务不可见
3.在数组中 ,说明事务未提交,不可见
4.不在数组中,说明事务已提交,可见。
数据不管发生多少次改变,一个事务不论何时查询得到的数据是一致的,我们成为“一致性读”。
1.版本未提交,不可见。
2.版本已提交,但是在创建视图后提交,不可见。
3.版本已提交,而且在试图创建前,可见。
更新逻辑:更新数据先读后写,而且此时的读,只能读取当前的值,成为“当前读”
select 语句加锁 也是当前读。
可重复读的核心就是一致性读。
事务更新数据的时候只能用当前读。
如果当前的的记录被其他事务占用,就需要进入锁等待。
可重复读的定义:一个事务启动的时候。能够看到所有已提交事务的结果,但之后的事务全部看不见。并且在本次事物中,不管在何时执行,结果都相同。
【但是事务自身更新的数据,它自己是要认的。】
读提交的逻辑和可重复读的逻辑类似,主要区别:
在可重复读隔离级别下,只需要在事务开始的时候创建一致性视图,之后的事务里面其他查询都公用整个一致性视图。
在读提交隔离级别,每个语句执行前都会算出一个新的视图。
对于可重复读,查询只承认在事务启动前已完成提交的数据。
对于读提交,查询只承认在语句启动前提交的数据。
用于记录,学习。