Mysql中的锁

一、锁的概念

锁是计算机协调多个线程并发访问某一资源的机制;

在数据库中,数据也是一种供许多用户共享的资源,如何保证数据并发的一致性、有效性,是所有数据必须解决的一个问题,锁冲突也是影响数据访问性的一个重要因素。

锁对数据库的性能而言显得尤为重要,也更加复杂。

二、Mysql中的锁

Mysql的锁机制比较简单,其中最显著的特点是不同的存储引擎,锁的机制不一样;

比如:MyISAM和MEMORY存储引擎采用的是表级锁;

           InnoDB采用的行级锁,也支持表级锁,但是默认情况下是采用的行级锁。

二、Mysql中的锁的特点

1. 表级锁:

    开销小,加锁快,不会出现死锁;锁定力度大,发生锁冲突的概率高,并发度低;

2. 行级锁:

     开销大,加锁慢,会出现死锁;锁定粒度小,发生冲突的概率低,并发度高。

3. 页面锁:

     开销和加锁时间介于行级锁 和 表级锁之间,会出现死锁;锁定粒度介于行级锁 和 表级锁之间;

4. 使用场景:

     表级锁适合于查询为主,只有少量按索引条件更新数据的应用,如OLAP系统;

     行级锁则适合于有大量安索引条件并发更新少量不同的数据,同时又有并发查询的应用;

三、MyISAM的表锁

1. 锁的简单介绍:

2. 锁定具体使用:

加锁  lock table 表名 READ

3. 具体事例:

LOCK TABLE demomyisam READ

3.1 先给表加读锁,

       结果:

  1.  在同一个session和另外的session,都是可以查询的;
  2.  在同一个session,不能做插入操作(更新操作也是同样的错误)
  3. (接着2 的操作)在另外的session,执行插入和更新操作会出现一直等待的情况,知道2中的解锁才行);

  4. 解锁操作:unlock tables;
  5. 对表 A 加锁,这时候不能创建另外的表;
  6. 对表 A 加锁,操作表 B ,同一个 session 执行插入和更新,都会报错(但是报错的信息和上一个是不一样的);
  7. 对表 A 加锁,操作表 B,不同的 session 执行插入和更新,都不会报错;

  8. mysql的锁,是不支持别名的;比如 加锁 LOCK TABLE demomyisam READ ,按说查询 demomyisam 是不会报错的,但是, SELECT * FROM demomyisam a ,就报错了;(结论:mysql的锁,是不支持别名的),这时候的话,需要这样加锁:LOCK TABLE demomyisam AS a READ 

3.2 先给表加写锁 

SELECT * FROM demomyisam

 

 四、InnoDb锁详解

1. 行锁:

  • 读作,又称共享锁,当一个事务对某几行上读锁的时候,允许其他的事物对这几行进行读操作,但是不允许其他进行写操作,也不允许其他的事物给这几行上排它锁,但是允许上读锁;
  • 写锁,又称排它锁,当一个事务对某几行上写锁的时候,不允许其他的事物写,但是允许读,更不允许其他的事物给这几个行上任何锁,包括写锁;

2. 加锁操作:

上共享锁语法:lock in share mode

SELECT * FROM 表名 WHERE (需要锁的条件) LOCK IN SHARE MODE;     

排它锁语法:  for update 

SELECT * FROM 表名 WHERE (需要锁的条件)FOR UPDATE;

3. InnoDb 行锁的特点

1.
BEGIN
select * from testdemo where id =1 for update
在另外一个session中
update testdemo set c1 = '1' where id = 2 成功
update testdemo set c1 = '1' where id = 1 等待
2.BEGIN
update testdemo set c1 = '1' where id = 1
在另外一个session中
update testdemo set c1 = '1' where id = 1 等待
3.
BEGIN
update testdemo set c1 = '1' where c1 = '1'
在另外一个session中
update testdemo set c1 = '2' where c1 = '2' 等待

3. 表锁:

和MyISAM差别不大,

注意:开启一个事务的时候会解锁表;

1.先来看下行锁
第一个session中
select * from testdemo where id =1 for update
第二个session
select * from testdemo where id =1 lock in share mode
回到第一个session UNLOCK TABLES 并不会解锁
使用commit 或者 begin或者ROLLBACK 才会解锁
2.再来看下表锁
lock table testdemo WRITE
使用commit,ROLLBACK 并不会解锁
使用UNLOCK TABLES 或者begin会解锁

posted @ 2019-07-11 12:36  宥宥美美  阅读(299)  评论(0编辑  收藏  举报