一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情
上篇文章详细演示了事务之间锁的关系,今天这篇文章我来和掘友们聊聊锁的分类。
1.从操作类型分为读锁、写锁
-
读锁 对于select查询语句来说就是读锁,又称s锁,在实际使用上也称为共享锁,在上篇文章已经详细演示过读锁之间是共享的,不会造成事务阻塞。
-
写锁
对于insert、update、delete对数据进行操作的语句就是写锁,写锁又称x锁,写锁之间会相互排斥、阻塞,又称独占锁,所以写锁是会阻塞事务的。
2.从锁定资源粒度分为表级锁、行级锁
- 表锁
innodb存储引擎下执行select、update、insert、delete语句时默认不会加表级锁,但是执行ddl语句比如alter table,drop table等语句时会加上表级锁,其实也很好理解,如果我们在修改表机构的时候这个时候某个语句来查询数据或者新增、修改数据,由于表结构在变如果不加表锁很有可能查不到数据或者新增修改失败,下面举个例子说明一下表级锁的使用,当前有表studdent,开启一个新事物尝试修改新增一个字段且事务不提交,开启另外一个事务去查询当前表的数据查看当前事务是否阻塞,假设当前表的数据足够多,你会发现增删改查的语句事务线程全部被阻塞,且会有卡顿的现象。
如上图所示,select语句查询有明显卡顿现象,所以在工作中尤其是线上环境不能随便修改表结构,否则会造成大量的请求堆积导致CPU飙升,mysql服务卡死。
当然除了ddl语句外innodb存储引擎也是可以手动增加表锁的,开启一个新事务,执行lock table test_index read;这样子就给表test_index加上了表级别的读锁,如果此时开启一个新事务去新增一条记录就会造成事务阻塞,如下图:
解锁需要手动执行:unlock table;
但是执行select语句还是可以查询出结果的,因为读锁是共享锁,如下图:
2.行锁
了解了表锁之后对于行锁,掘友们肯定就知道什么意思了,行锁顾名思义就是锁定数据的粒度为一行一行,对应的就是一条记录,这里不再演示,在上篇文章有详细演示过行锁的现象。
总结
不管是表锁还是行锁只要是读锁就是共享的不会造成事务阻塞,只要是有写锁,比如读、写,写、读,都会造成事务阻塞。