数据库隔离级别
-
读未提交:不管别人有没有提交,都可以读到他的数据
-
读提交:只能读别人提交的数据,但是自己本身读的数据可能发生修改
-
可重复读:只能读别人提交的数据,并且读了一次后,就一值使用之前读的数据
-
串行读:读写都获取表锁,读写互相阻塞
-
脏读:读到别人未提交的数据
-
幻读:进行一次全表更新操作,这时新增了一条数据,但是这条数据没有被更新,搞得好像幻觉一样 因为可重复读模式下,当自己查询到结果后,不管如何查询结果都是一样的(快照),本来查询没有的数据,在事务没有提交时怎么都查不出来,但是因为别的事务更新了数据库,本应是真实存在的数据,A事务却无法读到,但是提交事务后又可以读到了,就像幻觉一样。
-
MySQL使用间隙锁在可重复读模式下解决幻读,在查询语句后使用 for update添加间隙锁,主要表现为左开右闭。避免查询范围内的数据插入或者删除。
-
对于在索引上条件查询的for update:
-
唯一索引如果命中则添加行锁,没有命中则添加间隙锁。
-
普通索引不管是否命中都添加间隙锁。
-
没有索引的条件查询会添加表锁。
-
-
使用范围查询,锁住数据行范围内的所有间隙,使用=等号查询,如果是唯一索引就不会产生间隙锁,而是行锁。否则产生间隙锁
-
再探幻读!什么是幻读?为什么会产生幻读,MySQL中是怎么解决幻读的?_ZhaoSimonone的博客-CSDN博客_幻读
-
-
不可重复读:当别人修改了数据,自己之前读到的数据就被改变了
-
幻读和不可重复度的区别就在,一个反应在本数据行的属性发生更改,另一个反应为新增了一行数据,或者被删除了一行数据
-
-
第一类更新丢失:就是我更新了一个数据,但是别的事务撤销了,导致我的更新丢失
-
第二类更新丢失:就是我更新了一个数据,别人也更新,同时覆盖了我的更新数据
-
类型/错误 脏读 不可重复读 幻读 读未提交 ✔ √ √ 读提交 ✘ √ √ 可重复读 ✘ ✘ √ 串行读 ✘ ✘ ✘ 间隙锁的范围
begin;
select * from z where id=4 for update;
会锁住主键索引叶子节点的3的next指针。(为啥呢,需要你自己画主键索引的图)
begin;
select * from z where id=3 for update;
间隙锁会退化为行锁只锁叶子节点3 ,为什么因为没必要。不加间隙锁也不会打破上述的红色4个条件。
begin;
select * from z where id>4 for update;
叶子节点3及之后所有节点会加行锁并且他们的next指针会加锁,
begin;
select * from z where c=2 for update;
会发生锁表,因为c没有索引结构能存储行锁或者间隙锁。
```