前言:锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算机资源(如CPU、RAM、I/O等)的争用外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
1.锁的分类
#1.从对数据操作的类型来分
读锁(共享锁)和写锁(排它锁)
#2.从对数据操作的粒度来分
表锁和行锁
2.表锁(偏读)
特点:偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发度低。下面通过案例来说明表锁的一些情况。
#1.创建mylock表,并插入5条数据。注意数据引擎使用的是MyISAM。
drop table if exists mylock;
CREATE TABLE mylock (
id INT PRIMARY KEY auto_increment,
name VARCHAR (20) NOT NULL
) ENGINE MyISAM DEFAULT charset = utf8;
insert into mylock (name) values ('a');
insert into mylock (name) values ('b');
insert into mylock (name) values ('c');
insert into mylock (name) values ('d');
insert into mylock (name) values ('e');
#2.手动增加表锁命令。
lock table tablename1 read(write),tablename2 read(write);
#3.查看表是否被加锁。
如果In_use显示不为0,则表示表被加锁。
#4.释放表锁命令
unlock tables;
3.表锁案例
#1.在mylock表上加读锁。将当前会话命名为A。
在A会话中查询mylock中的数据。
数据查询正常,没有任何问题。
#2.再开一个会话,命名为B,查询mylock中的数据。
数据查询正常,没有任何问题。
#3.进行其他操作。
①在A会话中进行更新操作。
分析:
提示mylock表被加锁,不能进行更新操作。原因:mylock正被读锁锁住,未解锁不能进行更新操作。
②在B会话中读其他表。
分析:
A会话mylock表的读锁,并不影响B会话对mylock表和其他表的读操作。
③在A会话中读其他表。
分析:
由于A会话对mylock表加了读锁,在未解锁前,不能操作其他表。
④在B会话中修改mylock表中的内容。
分析:
出现了阻塞情况,原因:由于A会话对mylock表加锁,在锁未释放时,其他会话是不能对mylock表进行更新操作的。
⑤在A会话中对mylock表进行解锁操作,注意观察B会话中的变化。
分析:
在A会话中对mylock表解锁后,B会话更新操作成功,可看到B会话中的更新操作等待了22分钟。
总结
前提条件:在A会话中对mylock表加读锁。
①A、B会话都可对mylock表进行读操作,读锁为共享锁。
②A会话不能对mylock表进行更新操作,也不能对其他表进行操作。
③B会话可对其他表进行操作,对mylock表进行操作阻塞。
④A会话对mylock表解锁后,B会话对mylock表的操作成功。
by Shawn Chen,2018.6.28日,上午。