定义
锁是计算机协调多个进程或线程并发访问某一资源的机制。
锁的分类
按照对数据库操作的类型分可分为读锁(共享锁)和写锁(排它锁)
按照对数据库操作的粒度分可分为表锁和行锁
表锁
查看表上加过的锁
show open tables;
手动增加表锁
lock table 表名字1 read(write),表名字2 read(write)
释放表锁
unlock tables;
读锁案例
Session1获得表1的读锁
Session1 | Session2 |
获得表1的读锁 | 连接终端 |
当前Session1可以查询表1记录 | Session2也可以查询表1记录 |
当前Session1不能查询其他没有锁定的表 | Session2可以查询或更新未锁定的表 |
当前Session1插入或更新锁定的表将提示错误 | Session2插入或更新锁定表将会阻塞并等待获得锁 |
释放锁 | Session2获得锁,插入或更新操作完成 |
写锁案例
Session1获得表1写锁
Session1 | Session2 |
获得表1写锁 | 连接终端 |
当前Session1可以查询、更新、插入锁定的表 | Session2对锁定的表的查询被阻塞(由于mysql有缓存,查询时请不要跟Session1一致) |
释放锁 | Session2获得锁,查询完成 |
表锁分析
show status like 'table%';
Table_locks_immediate:产生表级锁的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1
Table_locks_waited:出现表级锁定争用而发生等待的次数
行锁
开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度最高。
对于表t_test情况如下
session1 | Session2 |
Session1设置不自动提交 set autocommit=0; | Session2也设置不自动提交 |
更新表中的数据,但不提交 update t_test set age=10 where id=1; | Session2也更新表数据,发生阻塞 update t_test set age=10 where id=1; |
间隙锁的危害
什么是间隙锁
当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做间隙,InnoDB也会对这个”间隙“加锁,这种锁机制就是间隙锁
危害
间隙锁有一个致命的弱点,就是当锁定一个范围后,即使某些不存在的键值也会被无辜锁定,而造成无法插入锁定键值范围内的任何数据。