一、数据库锁
1、锁的简介
为什么需要锁?
到淘宝上买一件商品,商品只有一件库存,这个时候如果还有另一个人买,那么如何解决是你买到还是另一个人买到的问题?
锁的概念:锁是计算机协调多个进程或线程并发访问某一资源的机制。
在数据库中,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。锁对数据库而言显得尤其重要,也更加复杂。
2、MySQL中的锁
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁(gap锁,间隙锁):开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。在这个部分只讲表级锁、行级锁,gap锁放到事务中讲。
表锁与行锁的使用场景:
- 表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如OLAP系统。
- 行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。
很难笼统地说哪种锁更好,只能就具体应用的特点来说哪种锁更合适。
3、MyISAM锁
MySQL的表级锁有两种模式:
- 表共享读锁(Table Read Lock)
- 表独占写锁(Table Write Lock)
3.1、共享读锁
语法:lock table 表名 read
1)对testmysam表进行加锁(只读)
lock table testmysam READ;
启动另外一个session:
select * from testmysam -- 可以查询
2)插入或者修改数据报错
insert into testmysam value(2);
update testmysam set id=2 where id=1;
3)在另外一个session中插入数据进入等待状态
insert into testmysam value(2); //等待.....
4)在同一个session中
insert into account value(4,'aa',123);
报错:ERROR 1100 (HY000): Table 'account' was not locked with LOCK TABLES
select * from account ;
报错:ERROR 1100 (HY000): Table 'account' was not locked with LOCK TABLES
5)在另外一个session中给其他表插入数据成功
insert into account value(4,'aa',123); -- 成功
加索在同一个session中:
select s.* from testmysam s;
报错:ERROR 1100 (HY000): Table 's' was not locked with LOCK TABLES
语法:lock table 表名 as 别名 read;
lock table testmysam as t READ;
select t.* from testmysam t;