数据库进阶笔记(四)——MySQL锁机制

  • 锁的分类
  • 表锁(偏向读)
  • 行锁(偏向写)


锁的分类

从对数据操作的类型:
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响。
写锁(排它锁):当前写操作没有完成前,他会阻断其他写锁和读锁。

从对数据操作的粒度来分:
表锁
行锁

表锁(偏向读)

手动增加表锁
lock table 表名1 read(write),表名2 read(write);
查看表上过的锁
show open tables;
释放表锁
unlock tables;

当我们在session1中未mylock添加read锁之后

session1				session2
		可以查询该表					可以查询该表
		不能查询其他没有锁定的表		可以查询或更新未锁定的表
		不能更新锁定的表				插入更新锁定表会阻塞

当我们在session1中未mylock添加write锁之后

session1					session2
		可以对锁定表完成查询+更新操作		对锁定表的查询阻塞

简言之:读锁会阻塞写,但是不会阻塞读。而写锁会把读和写都阻塞

行锁(偏向写)

InnoDB与MyISAM的最大不同有两点:一是支持事务;二是采用了行级锁

索引失效导致行锁变表锁

间隙锁:
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙”
InnoDB也会对这个间隙枷锁,这种锁机制就是所谓的间隙锁

间隙锁的危害:
因为Query执行过程中通过范围查找的话,他会锁定整个范围内所有的索引键值,即使这个键值并不存在。造成在锁定的时候无法插入锁定键值范围内的任何数据。

如何锁定一行?

select xxx... for update 锁定某一行之后,其他的操作会被阻塞,直到锁定的行的会话提交commit


行锁分析
show status like 'innodb_row_lock%';

java mysql锁表和解锁语句 mysql锁表操作_java mysql锁表和解锁语句

优化建议:
尽可能让所有数据检索都通过索引来完成,避免无索引升级为表锁
合理设计索引,尽量缩小锁的范围
尽可能 较少检索条件,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间长度
尽可能低级别事务隔离