Depth analysis of the MySQL transaction isolation

 

Outline

Today, under the principle of sharing the main MySQL transaction isolation level to achieve, because only InnoDB supports transactions, so here's transaction isolation level refers to the transaction isolation level in InnoDB.

 

Isolation Levels

  1. Read Uncommitted : A transaction can be read to modify another uncommitted transactions. This will bring dirty reads, phantom reads, non-repeatable read problem

  2. Read Committed : A transaction can only read modify another transaction has been submitted. It avoids the dirty read, there is still not repeatable read and phantom read problems

  3. Repeatable Read : the same reading result data returned several times in the same transaction are the same. It avoids dirty reads and non-repeatable read problem, but there is still phantom read

  4. Serialization : Transaction Serial trip. Avoids all these problems

 

These are the SQL-92 standard defines four levels of isolation. In MySQL, the default isolation level is REPEATABLE-READ (repeatable read), and solves the phantom read problem.

Note: Non-repeatable read with emphasis Update and delete, and phantom reads focus is insert.

MVCC

MVCC stands for multi-version concurrency control. Implementation Conformance read at MVCC makes InnoDB transaction isolation level is assured.

It simply is to query some lines are being updated by another transaction, and can see the value before they are updated. It used to enhance concurrency is a powerful technology that can make queries without waiting for another transaction to release the lock.

As shown below:

 

Each row will increase MVCC three fields, namely: DB-TRX-ID, DB-ROLL-PTR, DB-ROW-ID

Additions and deletions to change search

In InnoDB, to increase each row two hidden fields to achieve MVCC, a data line is used to record the creation time, the expiration time for another record row.

In practice, the storage is not time, but the version number of the transaction, each open a new transaction, the transaction version number is incremented. Therefore CRUD effects on the version number as follows:

select:
读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本的记录。这样可以保证在读取之前记录都是存在的

insert:
将当前事务的版本号保存至行的创建版本号

update
新插入一行,并以当前事务版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号

delete
将当前事务版本号保存至行的删除版本号

快照读和当前读

  • 快照读:读取的是快照版本,也就是历史版本

  • 当前读:读取的是最新版版

普通的 select 就是快照读,而 update,delete,insert,select...LOCK In SHARE MODE,SELECT...for update 就是当前读

一致性非锁定读和锁定读

首先看看下面的图:

 

1、锁定读

在一个事务中,标准的SELECT语句是不会加锁,但是有两种情况例外。

  • SELECT ... LOCK IN SHARE MODE 

  • SELECT ... FOR UPDATE

SELECT ... LOCK IN SHARE MODE:给记录假设共享锁,这样其他事务职能读不能修改,直到当前事务提交

SELECT ... FOR UPDATE:给索引记录加锁,这种情况跟UPDATE的加锁情况是一样的

2、一致性非锁定读

consistent read(一致性读),InnoDB用多版本来提供查询数据库在某个时间点的快照。

如果隔离级别是REPEATABLE READ,那么在同一个事务中的所有一致性读都读的是事务中第一个的读读到的快照;如果是READ COMMITTED,那么一个事务中的每一个一致性读都会读到它自己刷新的快照版本。

consistent read(一致性读)是READ COMMITTED和REPEATABLE READ隔离级别下普通SELECT语句默认的模式。一致性读不会给它锁访问的表加任何形式的锁,因此其他事务可以同时并发的修改它们

  1. Record Locks(记录锁):在索引记录上加锁

  2. Gap Locks(间隙锁):在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录之后加锁

  3. Next-Key Locks:在索引记录上加锁,并且在索引记录之前的间隙加锁。相当于Record Locks与Gap Locks的一个结合

假如一个索引包含以下几个值:10,11,13,20.那么这个索引的next-key锁将会覆盖以下区间:

(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

总结

在默认的隔离级别中,普通的SELECT用的是一致性读不加锁。而对于锁定读,UPDATE和DELETE,则需要加锁,至于加什么锁是有不同情况的。

如果对一个唯一索引使用了唯一的检索条件,那么只需要锁定相应的索引记录就好;如果是没有使用唯一索引作为检索条件,或者用到了索引范围扫描,那么将会使用间隙锁或者next-key锁来以此阻塞其他会话向这个范围内的间隙插入数据

利用MVCC实现一致性非锁定读,保证在同一个事务中多次读取相同的数据返回的结果是一样的,解决了不可重复读问题.

利用Gap Locks和Next-key可以阻止其他事务在锁定区间内插入数据,解决了幻读问题.

总之,MySQL的默认隔离级别的实现依赖于MVCC和锁,准确点说就是一致性读和锁。

Guess you like

Origin www.cnblogs.com/williamjie/p/11083915.html