数据库两大神器【索引和锁】 (4)

看完上面的有没有发现,在一开始所说的:X锁,S锁,读锁,写锁,共享锁,排它锁其实总共就两个锁,只不过它们有多个名字罢了~~~

Intention locks do not block anything except full table requests (for example, LOCK TABLES ... WRITE). The main purpose of intention locks is to show that someone is locking a row, or going to lock a row in the table.

另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁

意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

意向锁也是数据库隐式帮我们做了,不需要程序员操心

参考资料:

https://www.zhihu.com/question/51513268

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

2.2.1MVCC和事务的隔离级别

数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致不同事务的隔离级别

MVCC(Multi-Version Concurrency Control)多版本并发控制,可以简单地认为:MVCC就是行级锁的一个变种(升级版)

事务的隔离级别就是通过锁的机制来实现,只不过隐藏了加锁细节

表锁中我们读写是阻塞的,基于提升并发性能的考虑,MVCC一般读写是不阻塞的(所以说MVCC很多情况下避免了加锁的操作)

MVCC实现的读写不阻塞正如其名:多版本并发控制--->通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),并用这个快照来提供一定级别(语句级或事务级)的一致性读取。从用户的角度来看,好像是数据库可以提供同一数据的多个版本

快照有两个级别

语句级

针对于Read committed隔离级别

事务级别

针对于Repeatable read隔离级别

我们在初学的时候已经知道,事务的隔离级别有4种

Read uncommitted

会出现脏读,不可重复读,幻读

Read committed

会出现不可重复读,幻读

Repeatable read

会出现幻读(但在Mysql实现的Repeatable read配合gap锁不会出现幻读!)

Serializable

串行,避免以上的情况!

Read uncommitted会出现的现象--->脏读:一个事务读取到另外一个事务未提交的数据

例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。

出现脏读的本质就是因为操作(修改)完该数据就立马释放掉锁,导致读的数据就变成了无用的或者是错误的数据

Read committed避免脏读的做法其实很简单:

就是把释放锁的位置调整到事务提交之后,此时在事务提交前,其他进程是无法对该行数据进行读取的,包括任何操作

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywygj.html