mysql隔离级别

事务并发的三种问题:

脏读:读取了别的事务未提交的数据。
不可重复读:你读取过的数据 , 再次读取出来被人改了。
幻读:同一个事务,第1次和第2次读出来的记录数不一样。

隔离级别

读未提交

读已提交

可重复读

可串行化

 

ReadUncommitted

ReadCommitted

REPEATABLE READ

SERIALIZABL

理论锁

写事务阻塞写,但不阻塞读。

写事务会阻塞写、读事务,但是读不阻塞写,

写阻塞读写,读阻塞写(锁所有行)

读加共享锁,写加排他锁(锁表)

Mysql实际锁

只有写阻塞写

只有写阻塞写

只有写阻塞写

写阻塞读、写,

读阻塞写。

可能存在问题

脏读、不可重复读、幻读

不可重复读、幻读

幻读

Mysql实际存在问题

脏读、不可重复读、幻读

不可重复读、幻读

[读未提交]

其他事务和非事务都能读取事务A更改的中间数据。

[读已提交]

写并不会阻塞读,只不过读的是当前数据库的值。

[可重复读]

RR级别中,通过以乐观锁为基础的MVCC机制(多版本并发控制),虽然让数据变得可重复读,但我们读到的数据可能是历史数据,不是数据库当前的数据。

一句话总结:在同一个事务内的查询都是事务开始时刻一致的

[实际情况,RR级别不存在幻读]

mysqlInnoDB通过行锁和GAP锁结合形成的Next-Key锁解决了RR级别时的幻读问题。

[Next-Key锁]

行锁防止别的事务修改或删除,GAP锁防止别的事务新增,行锁和GAP锁结合形成的的Next-Key锁。

[所谓阻塞,是阻塞到什么时候?]

例如:事务A:写(10s)读(1s),B:读(1s)写(2s)。

执行:先后开启A、B事务,然后A执行写;在A执行写的后立即执行B所有操作,B的写会被阻塞。注意是阻塞到A的commit为止,而不是A的写执行完,A在读(1s)时,B的写还会被阻塞。

(名字:Gap锁:间隙锁。Next-Key Lock:后码锁Record Lock:行锁、记录锁。)

1.InnoDB三种行锁定:行锁(Record Lock)、间隙锁(Gap Lock)、Next-Key Lock 。

2.行锁锁定的是索引记录,而不是行数据,也就是说锁定的是key

3.Next-Key Lock =行锁和间隙锁。

4. InnoDB通过行锁和间隙锁结合形成的Next-Key锁解决了RR级别时的幻读问题。

5. 间隙锁(Gap Lock)一般是针对非唯一索引而言。

6.Gap锁只会阻塞insert操作。(因为最近的索引间隙里是没有数据的,也不可能锁其他操作)

7.锁间隙,是锁的索引的间隙,左闭右开。

8.Next-Key Lock:先加行锁再加间隙锁。

9.可以手动给sql加共享锁或者排它锁。

select * from t1 where b=3 forupdate#加排他锁X

select * from db1.t1 where b=3 lock in share mode;#加共享锁S

10. 使用next-key lock的必备条件:

1.RR级别或以上

2.innodb_locks_unsafe_for_binlog的默认值0没有更改。

3.非唯一索引。

11. 如果更新没走索引,会加表锁。走非唯一索引会加Next-Key Lock。走唯一索引加行锁。解释:索引唯一,InnoDB会把锁降级成Record Lock。

12.

锁按照精度分为:行锁、表锁、意向锁。

https://blog.csdn.net/claram/article/details/54023216(待看)

Mysql加锁详解:http://hedengcheng.com/?p=771

因为如果测试数据较少的话,可能优化器直接走全表扫描,那就导致锁住所有记录,无法模拟出Gap锁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章