MySQL事务隔离级别实现原理

在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里讨论的事务隔离级别指的是MySQL InnoDB下的事务隔离级别,一般而言,隔离级别分为:
读未提交:一个事务可以读取到另一个事务未提交的修改。这会带来脏读、幻读、不可重复读问题,很少使用这个级别。
读已提交:一个事务只能读取另一个事务已经提交的修改。其避免了脏读,但仍然存在不可重复读和幻读问题。
可重复读:同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但幻读依然存在。
串行化:事务串行执行。避免了以上所有问题。
以上是SQL-92标准中定义的四种隔离级别。在MySQL中,默认的隔离级别是REPEATABLE-READ(可重复读),并且解决了幻读问题。简单的来说,mysql的默认隔离级别解决了脏读、不可重复读问题。不可重复读重点在于update和delete,而幻读的重点在于insert。在这里,我们只讨论可重复读。
这里有些术语需要了解下:
MVCC:multiversion concurrency control的全称是“多版本并发控制”。
这项技术使得InnoDB在事务隔离级别下执行一致性读操作有了保证,换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大的技术,因为这样的一来的话查询就不用等待另一个事务释放锁。这项技术在数据库领域并不是普遍使用的。一些其它的数据库产品,以及mysql其它的存储引擎并不支持它。
行记录的可见性:MVCC实现了多个并发事务更新同一行记录会时产生多个记录版本,那问题来了,新开始的事务如果要查询这行记录,应该获取到哪个版本呢?即哪个版本对这个事务是可见的。这个问题就是行记录的可见性问题。
InnoDB会给数据库中的每一行增加三个字段,它们分别是DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID。
DB_TRX_ID表示最后一个事务的ID,每开启一个新事务,事务的版本号就会递增;
DB_ROLL_PTR指向当前记录项的undo log信息;
DB_ROW_ID标识插入的新的数据行的id。

1、事务隔离级别为读提交时,写数据只会锁住相应的行
2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
3、事务隔离级别为串行化时,读写数据都会锁住整张表
4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。

 

你可能感兴趣的:(数据库)