mysql间隙锁、表锁、行锁,读锁(共享锁)、写锁(排他锁),意向锁

1.间隙锁(Gap锁)

间隙锁是一个在索引记录之间的间隙上的锁。
例:

mysql间隙锁、表锁、行锁,读锁(共享锁)、写锁(排他锁),意向锁_第1张图片

 间隙锁的作用:

保证某个间隙内的数据在锁定情况下不会发生任何变化。比如mysql默认隔离级别下的可重复读(RR)

当使用唯一索引来搜索唯一行的语句时,不需要间隙锁定。如下面语句的id列有唯一索引,此时只会对id值为10 的行使用记录锁
select * from t where id = 10 for update;注意:普通查询是快照读,不需要加锁。

如果上面语句中id列没有建立索引或者是非唯一索引时,则语句会产生产生间隙锁。

gap锁如何锁区间?

通过InnoDB中索引树的结构可以了解到:gap锁的关键就是锁住索引树的叶子结点之间的间隙,不让新的记录插入到间隙之中。

2.表锁 :

表锁就是锁住整张表,其他用户对该表的任何操作都受影响,具体影响取决于锁的形式。
MySQL的表锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock):
 表共享读锁(Table Read Lock):不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;
表独占写锁:会阻塞其他用户对同一表的读和写操作;

2.1表锁细节需要区分是MyISAM还是InnoDB

        MyISAM:        
                MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等),会自动给涉及的表加写锁,这个过程并不需要用用户干预。

        InnoDB:
                必须显示加表锁语句
                注意:如果没有索引,InnoDB的行锁会升级为表锁,效果和表锁一样,锁住全部索引。

3.行锁(record lock)

行锁就是对具体的索引数据进行加锁,与表锁相比,粒度更小,减少竞争

行锁不是只能在一行上加锁,可以是若干行,可以是连续的,也可以是跳跃的

对于UPDATE、DELETE、INSERT语句,InnoDB会自动给涉及的数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁。

4.共享锁(读锁)和排他锁(写锁)

InnoDB实现了以下两种类型的行锁:
        共享锁(s):共享锁又称为读锁,简称S锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

        排他锁(X):排他锁又称为写锁,简称X锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据进行读取和修改。

共享锁=读锁、排他锁=写锁,确切来说mysql没有读锁和写锁概念的,但是在实际应用中,读锁表示并发操作,写锁不支持并发,必须阻塞,因此可以这样划等号。但严格来说,在计算机概念中,不是所有的读锁都是支持并发的。

 事务可以通过以下语句显示给记录集加共享锁或排他锁:

共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE

排他锁(X):SELECT * FROM table_name WHERE ...FOR UPDATE

InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给设计到的数据加上排他锁,select语句默认不会加任何锁类型。

5.意向锁

意向锁是InnoDB自动加的,不需用户干预。

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

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

事务在请求行锁中的共享锁和排他锁前,会先自动获得意向锁。

你可能感兴趣的:(1024程序员节)