Mysql事务的可重复读

Repeatable Read 即 可重复读。Mysql默认的隔离级别。

理解了不可重复读,再来看可重复读就简单的多,也就是不管其它事务B是否修改了该数据,事务A内读多次该数据都是一致的,当然有个前提就是事物A在多次读之前都没有对数据进行修改,插入,删除的操作,否则怎么会一致呢。

还有个小提示就是:事务A开启后,如果还没有执行任何语句,事务B进行了更新操作,那么事务A的第一次select结果一定是事物B操作后的。

看图说话:

隔离级别

下图事务A读两次,第一次读bill有1000块钱,红框表示事务B进行了update操作。

事务A

事务B更新

事务A第二次读的结果bill的钱仍是1000,与事务B更新后读出的结果不同。

事务A里读了两次都是1000,即可重复读。

可是,如果事务B更新为999块钱时,事务A进行更新操作把bill的钱减1,然后事务A再次读取,会显示Bill有多少钱呢,999还是998?在事务A执行中间,事务B进行了插入或者删除操作呢?

看图继续:

事务B

事务A

从上图可知,事务B的插入和删除,对事务A依然是不可见的,即不影响事务A的多次读的结果,也就是说仍然是可重复读即数据一致。

然而,一旦事务A有修改操作,就会在事务B更新的结果上进行修改,再次读,就会读出更新后的结果。

这么看,多次读的结果是否是一致的,非很多场景,依赖于其它事务干了什么,依赖于本事务干了什么,不可笼统的讲。

这个场景,如果拿出来面试,血流成河。

Mysql事务的不可重复读

事务的ACID属性中的I是Isolation,言外之意就是多个事务之间的数据隔离问题,所以在谈论事务时一定是在多个事务即一般意义上是多个数据库连接同时操作的数据库的情况下。单个事务内是没有isolation概念的,即单个事务内的数据无隔离性,全可视。

四种隔离级别中的

第一种:Read Uncommitted,几乎无实际用处,请忽略。

第二种:Read Committed也叫做Non Repeatable Read,即不可重复读。

这个级别是多数数据库的默认的隔离级别,但是MYSQL不是。

不可重复读?指的是什么?

首先要搞清楚,是谁第一次读、第二次读?是指在一个事务内的两次select,也就是在一个数据库链接中操作。

为何叫不可?是因为这个级别的事务A开启后,第一次select后,另一个事务B有update这条记录的操作,并且commit了,再之后这个事务A再次select,得到的结果和第一次select的结果不同,这就是不可重复读。

下面我们看下实验(mysql版本5.6.17):

表结构

表数据

设置隔离级别

事务A先select(红框上面),然后事务B(另一个数据库连接)update了记录为999(红框表示有事务B执行).

事务A:

事务B:

然后事务A再次执行select(红框下面),读出的结果与第一次不同(bill第一次有1000,第二次有999,因为两次读中间,事务B修改了bill的钱)。

这就是不可重复读,但是只是update情况,那么insert和delete情况如何?继续看下。

事务B中进行insert操作,然后事务A读一下,然后事务B再次delete,然后事务A再读。

事务B

事务A

可见,这个级别是彻底的不可重复读。

如果事务A中,先读,事务B更新,事物A再更新同一条记录的同一个字段,然后事务A再读该字段,会出现什么情况?这个字段的值该如何变化?

这个情形,不可重复读和可重复读是一致的,见下一篇《Mysql事务的可重复读》。

色诺芬

既然自制能够保证在最为平庸的事物中找到“难以忘怀的”乐趣,而试图寻找快感的大多数做法因缺乏自我主宰结果一无所获,那么自制则能比它物获得更多快感或找到最佳快感。《色诺芬与苏格拉底》,p39。

苏格拉底还是个节食主义者!

理学vs心学

王守仁说看见小孩掉进井里,则必有恻隐之心;小孩看见鸟兽哀鸣,则必有不忍之心,所以其仁必与孺子鸟兽为一体。

可这正说明心与仁的分离,仁乃心外之物。何以证明心即理呢,反而恰好证明性即理。

王守仁糊涂。