锁机制的作用:
解决因为资源共享,而造成的并发问题。
没有锁机制时:
例如一号用户和二号用户都要去买同一件商品(假如这件商品是一件衣服),一号用户手速稍微快了一些,于是就先买到了这件衣服,但是因为没有“锁机制”,于是就造成了二号用户不知道这件衣服已经被人买了,所以就造成了“并发问题”。
有锁机制时:
但是有了“锁机制”,一号用户在买了衣服之后就会“对衣服进行加锁”,二号用户看到“衣服被加锁了”,于是就去“等待着衣服被解锁”。
在“衣服未被解锁”的过程中,衣服则会被一号用户进行“试穿”、“下单”、“付款”、“打包”、或者“不满意,取消订单”一系列的操作,这一系列操作之后“衣服会被解锁”。
如果一号用户这边觉得衣服还行打算买下来,在买完之后“衣服就会被解锁”,二号用户这边看到“衣服被解锁了”就会去查看衣服是否还存在,很明显已经不存在了,因为一号用户已经把衣服买了,如果一号用户“不满意,取消订单”,那么二号用户这边就可以购买这件衣服。
因此通过锁机制就很好的解决了买衣服造成的并发问题。
1、读锁(也叫“共享锁”):
对同一个数据(衣服),多个读操作可以同时进行,互不干扰。
2、写锁(也叫“互斥锁”)
如果当前写操作没有完毕(买衣服的一系列操作),则无法进行其他的读操作、写操作。
1、表锁 :
一次性对一张表整体加锁。如MyISAM存储引擎使用表锁,开销小、加锁快;无死锁;但锁的范围大,容易发生锁冲突、并发度低。
2、行锁(与表锁的特性完全相反):
一次性对一条数据加锁。如InnoDB存储引擎使用行锁,开销大,加锁慢;容易出现死锁;锁的范围较小,不易发生锁冲突,并发度高(很小概率发生高并发问题:脏读、幻读、不可重复度、丢失更新等问题)。
3、页锁(几乎遇不见)
页锁的开销介于表锁和行锁之间,会出现死锁。锁定粒度介于表锁和行锁之间,并发度一般。
1、创建两张表,表table和表lock
create table tab(
id int primary key auto_increment ,
name varchar(20)
)engine myisam;
insert into tab(name) values('tab1');
insert into tab(name) values('tab2');
insert into tab(name) values('tab3');
insert into tab(name) values('tab4');
insert into tab(name) values('tab5');
create table locktab(
id int primary key auto_increment ,
name varchar(20)
)engine myisam;
insert into locktab(name) values('locktab1');
insert into locktab(name) values('locktab2');
insert into locktab(name) values('locktab3');
insert into locktab(name) values('locktab4');
insert into locktab(name) values('locktab5');
2、再新建两个会话

1、增加锁:
lock table 表1 read/write,表2 read/write,...;
2、释放锁:
unlock tables;
3、查看加锁的表:
show open tables;
给表locktab加读锁:
lock table locktab read;
select * from locktab; --执行读操作(查),可以

delete from locktab where id =1; --执行写操作(增删改),不可以

操作没有加锁的表tab:
select * from tab; --读操作,不可以
delete from tab where id = 1; --写操作,不可以

结论:
1、如果某一个会话对A表加了read锁,则该会话可以对A表进行读操作、不能进行写操作;且该会话不能对其他表进行读、写操作。
2、即如果给A表加了读锁,则当前会话只能对A表进行读操作。
操作加锁了的表locktab:
select * from locktab; --读操作(查),可以

delete from locktab where id =1 ; --写操作,会“等待”会话192.168.11.101(1)将锁释放

操作没有加锁的表tab:
select * from tab; --读操作(查),可以
delete from tab where id = 1; --写操作(增删改),可以

再来在“会话192.168.11.101(1)”中把锁释放了,看看“delete from locktab where id =1;”是否会释放阻塞: