一 mysql的悲观锁 - 以行锁做示例
每次拿数据的时候都认为别的线程会修改数据,所以每次拿数据的时候都会给数据上锁。上锁之后,当别的线程想要拿数据时,就会阻塞。直到给数据上锁的线程将事务提交或者回滚。传统的关系数据库里面很多用了这种锁机制,比如行锁,表锁,共享锁,排他锁等,都是在做操作之前先上锁。
下面的图从网上粘的,用mysql的两个视窗演示一下行锁(左边先执行)
(1) 左边的线程,在事务中通过select for update语句给sid=1的数据行上了锁,右边的线程此时可以使用select语句读取数据,但是如果也使用select for update语句就会阻塞,使用update, add, delete也会阻塞。 而当左边的线程将事务提交(或者回滚),右边的线程就会获取锁,线程不再阻塞
(2) 此时右边的线程获取锁,左边的线程执行此类操作,也会被阻塞。
(3) 当然,select都不行,update等写操作也要阻塞等待。for update是排他锁
二 mysql的锁粒度分类
1 行级锁
(1) 描述
行级锁是mysql中锁定粒度最细的一种锁。表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突,其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁
(2)特点
开销大,加锁慢,会出现死锁。发生锁冲突的概率最低,并发度也最高。
2 表级锁
(1) 描述
表级锁是mysql中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分mysql引擎支持。最常使用的MyISAM与InnoDB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)
(2)特点
开销小,加锁快,不会出现死锁。发生锁冲突的概率最高,并发度也最低。
3 页级锁
(1) 描述
页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB 支持页级锁。
(2)特点
开销和加锁时间界于表锁和行锁之间;会出现