前言更新操作需要锁数据,SQL事务的执行一定不能没有锁。共享锁和排它锁tablelockrowlockRecordLockgaplockGapLockrowlock+gaplockNext-KeyLock加锁场景(lockingsql)1.共享锁和排它锁排它锁(X锁),当前事务到记录后加锁(insertupdatedelete),可以读写,其他事务不能加任何锁。共享锁(S锁)是指当前事务锁定一条记录后,其他事务也可以给当前记录加共享锁。共享锁仅用于锁定读取,如果需要更新数据则不允许使用。2、表锁是针对数据库表的锁,又称表锁,开销小,加锁速度快;不会有僵局;锁粒度大,锁冲突概率最高,并发度最低。MySQL表级锁有两种模式:表共享锁(TableReadLock)和表独占写锁(TableWriteLock)。myisam、内存和合并存储引擎只支持表锁。表级别的AUTO_INC锁是给表的某一列加上AUTO_INCREDMENT属性。插入数据后,可以不指定该字段,系统会自动为其赋值。这时候需要AUTO_INC锁来获取自增值。3、行锁RecordLockinnodb同时支持表锁和行锁。行锁是对一行记录的锁。行锁:开销大,加锁慢;会发生死锁;锁粒度最小,锁冲突概率最低,并发度最高。InnoDB在执行selectupdatedeleteinsert语句的时候不会给表加S锁和X锁,因为表锁功能强大,容易阻塞。单个索引记录被锁定,记录锁始终锁定索引,而不是记录本身。即使表上没有索引,那么InnoDB也会在后台创建一个隐藏的聚簇主键索引,然后隐藏的就是加锁的聚簇主键索引。所以当一个sql没有使用任何索引时,那么每个聚簇索引后面都会加一个X锁。什么是意向锁?如果有行锁,想锁表怎么办?遍历表看有没有行锁是浪费时间。这时候意向锁就登场了!意向共享锁(IS锁):事务在给行记录加了S锁的同时,也给表加了IS锁。意向排他锁(IX锁):当一个事务给一个行记录加一个X锁的时候,它也给这个表加了一个IX锁。有了意向锁,可以不用遍历数据,直接判断是否可以锁表。4.GapLockMysql在可重复读隔离级别解决幻读。有两种实现方法。一种是通过MVCC方案解决;另一个是通过锁定方案解决的。但是事务加锁时,记录不存在,不能加行锁。你需要依靠间隙锁(gaplock)来实现。比如对id=10的记录加一个间隙锁,锁定区间(5,10)。另一个事务要插入id=8的记录,会先定位到id=10的记录,然后发现有间隙锁,然后阻塞,直到第一个事务释放间隙锁,才可以在(5,10)区间插入记录。间隙锁只是为了防止插入幻象记录,并不限制其他事务继续对记录加行锁或间隙锁。5.Rowlock+gaplockNext-KeyLocknext-keylock的本质是recordlock和gaplock的结合。它不仅可以保护记录,还可以防止其他事务将新记录插入到被保护记录前面的空隙中。6、加锁场景(可重复读隔离级别加锁sql,忽略二级索引的加锁操作)快照读:读取数据库记录的快照版本,sql执行前产生的最新数据和当前事务ID。当前读取:读取提交事务产生的数据,大于当前事务ID的提交事务产生的数据也可以读取。selectfrom不加任何锁,读取快照。selectforupdateclusteredindexplusXlock,currentlyread.Selectlockinsharemode使用当前读取向聚簇索引添加行级S锁。插入、更新和删除语句的锁定状态。Insert在可重复读级别添加next-keylockdelete,update在聚集索引记录上添加X锁。
