事务到底是隔离还是不隔离?

丁奇《Mysql实战45讲》 理解

在RR隔离级别下,我们说过事务开启后会创建一个视图read-view,之后事务执行期间,即使有其他事务修改了数据,并不影响我们见到的,因为我们看的是这个read-view。

但是,如果当我们要更新一行的数据时,恰好这行被另外一个事务锁住,我们进入等待队列,当这个事务提交之后,我们拿到这个行锁,去更新这一行数据时候,我们看到的是read-view还是事务更新之后的数据呢?(实验证明并不是看到的read-view)

所以这里有这个疑惑点,难道理论被推翻了吗?

答案:

( 一致性读肯定是读取在某个时间点已经提交了的数据,有个特例:本事务中修改的数据,即使未提交的数据也可以在本事务的后面部分读取到 )

数据表中的一行记录,其实可能会有多个版本,每个版本有自己的row_trx_id,这个id标记着哪个事务操作过这行数据。

而要获取旧版本的数据行时,可以通过最新版本的数据和最新版本到目的版本之间的 Undo Logs 计算出来 , 需要某个版本的row,实际上是当前row结合undo log算出来的。row的多个版本数据物理上不存在(并不存在于磁盘)。为了节省空间,但需要时根据undolog算出来。

当前读和一致性读

除了 update 语句外,select 语句如果加锁,也是当前读。 当前读必须要读到最新的数据

mysql> select k from t where id=1 lock in share mode;
mysql> select k from t where id=1 for update;

读提交的逻辑和可重复读的逻辑类似,它们最主要的区别是:在可重复读隔离级别下,只需要在事务开始的时候创建一致性视图,之后事务里的其他查询都共用这个一致性视图;在读提交隔离级别下,每一个语句执行前都会重新算出一个新的视图。

这里需要说明一下,“start transaction with consistent snapshot; ”的意思是从这个语句开始,创建一个持续整个事务的一致性快照。所以,在读提交隔离级别下,这个用法就没意义了,等效于普通的 start transaction。

posted @ 2021-06-06 15:48  hochan_100  阅读(23)  评论(0)    收藏  举报