X锁 | S锁 | |
---|---|---|
X锁 | 冲突 | 冲突 |
S锁 | 冲突 | 不冲突 |
select * from table_a lock in share modemysql
使用场景:读出数据后其余事务不能修改,但本身也不必定能修改,由于其余事务也能够加读锁。主要用来保证数据在本事务内值不会变。但实际开发中用得比较少。sql
select * from table_a for update 以及 DELETE/UPDATE/INSERT(插入后未提交的数据也会加写锁)性能
使用场景:只有本事务才能够修改这些数据,其余事务加锁会阻塞。通常开发过程当中大部分接触到的锁都是写锁。索引
行锁又分为:事务
select * from table_a where a = 1 for update开发
事务隔离级别为读提交时 会对查询出的全部每条数据加行锁(单个行记录上锁),但此时其余事务能够针对这个数据范围insert形成幻读。table
当事务隔离级别为可重复读时(mysql默认的事务隔离级别) 若是走索引,mysql经过索引知道数据的范围,会对查询出的数据范围间隙及数据自己加锁,其余事务针对这个数据范围写操做都会阻塞,包括insert在这个间隙范围内的操做,以免幻读。class
但若是sql语句不走索引全表扫描,此时mysql并不知道数据范围,mysql只能对全部的数据和间隙上锁以免幻读。date
表锁在InnoDB中应用不多,写操做是不会加表级别的锁。select
而DDL语句也会发生阻塞,这个过程是经过使用元数据锁(Metadata Locks,MDL)来实现的,并非表级别的锁。 可是能够用过如下方式加表锁
可是不建议使用,由于InnoDB的优势就是行锁,表锁性能差。