前言

  数据库的锁主要用来保证数据的一致性的。MyISAM存储引擎只支持表锁,InnoDB存储引擎既支持行锁,也支持表锁,但默认情况下是采用行锁。

一、锁分类

 1.按照对数据操作的类型分:读锁,写锁

  • 读锁:也称为共享锁。 针对同一资源,多个并发读操作可以并行执行,并且互不影响,但是不能写
  • 写锁:也称排它锁。当前线程写数据的时候,会阻塞其它线程来读取数据 或者 写数据

  注:读锁和写锁都是阻塞锁。

 2.按照数据操作的粒度:表锁,行锁,页锁

  • 表锁:开销小,加锁快,主要在myisam存储引擎中出现。特点:锁住整个表,开销小,加锁快,无死锁情况, 锁的粒度大,在并发情况下,产生锁等待的概率比较高,所以说,支持的并发数比较低,一般用于查找
  • 行锁:开销大,加锁慢,锁定单独的某个表中的某一行记录,主要用于innodb存储引擎。特点:有死锁情况,锁定粒度最小,发生锁冲突的概率最低,支持的并发数也最高
  • 页锁:开销和加锁时间界于表锁和行锁之间。会出现死锁,锁定粒度界于表锁和行锁之间,并发度一般

二、加锁与解锁

 1.手动增加表锁

   lock table 表名 [read|write],表名 [read|write]…

 2.解锁

   unlock tables;

 3.查看哪些表被锁

   show open tables;

三、表锁案例

 1.读锁

  create table lock_one(
  id int primary key auto_increment,
  col int
  )engine=myisam;   insert into lock_one(col) values (1);
  insert into lock_one(col) values (2);
  insert into lock_one(col) values (3);

  下面我们模拟两个用户,即两个线程连接数据库,开启两个xsheel窗口,连接到mysql:

  1) 在会话1中对lock_one表增加读锁

    lock table lock_one read;

  2) 在当前会话(会话1)中是否可以select该表呢,也就是说对 lock_one增加了读锁后,在当前会话中是否可以读呢?

   select * from lock_one;

   答案是可以的。

  3) 在另一个会话中(会话2)是否可以select该表呢?

   答案也是可以的。

  4) 那么在会话1中是否可以查询其他表呢?

     例如,查询 users表:select * from users;

   

   我们发现是不可以查询其他表的,这是因为当前会话已经对lock_one表加上了锁,即当前线程锁住了lock_one表,只可以操作lock_one表,就不可以查询其他的表。

  5) 问题来了,会话2是否可以查询其他表呢?

   select * from users;

     

   我们发现是可以的。因为会话2和会话1是没有关系的,会话2查询会话1锁住的表都可以,查询没有锁住的 肯定是可以的。

  6) 在会话1中是否可以更新(增删改)锁住的lock_one表呢?

   update lock_one set col=66 where id=1;

     

   发现是不可以的,因为我们对 lock_one表加了 读锁,所以是不可以 进行写操作的。

  7) 在会话2中是否可以更新(增删改)会话1中锁住的lock_one表呢?

    

    我们发现是没有执行结果的,也就是说 正在等待更新,在阻塞等待中。因为我们在会话1中对lock_one中增加了读锁,其他人只有读的操作,没有写的操作。

  8) 在会话1中 对lock_one进行解锁时,会话2中的更新(增删改)操作 就会立即执行。

   

 2.写锁

  1) 在会话1中对lock_one表增加写锁

   lock table lock_one write;

  2) 在会话1中查询该表

   select * from lock_one;

     我们发现是可以的。

3) 在会话2中查询该表

    

    我们发现是没有执行结果的,也就是说 处于阻塞状态。因为写锁是排它锁,其他用户线程不可以读取当前锁住的表,只有解锁之后 其他用户线程才可以执行select

    

  4) 在会话1中对lock_one进行写锁后,会话1会否可以查询其他表呢?

   select * from users;

     

   我们发现是不可以的。道理和读锁的时候一样,当前会话已经对lock_one表加上了锁,即当前线程锁住了lock_one表,只可以操作lock_one表,就不可以查询其他的表。

  5) 那么在会话2中是否可以查询其他表呢?

   答案肯定是可以的。因为之和锁的表有关系,和其他表没有任何关系。

  6) 在会话1中是否可以进行写(增删改)操作呢?

     答案一定是可以的。因为会话1对lock_one表进行了写锁操作,也就是只可以写。

  7) 在会话2中是否可以进行写(增删改)操作呢?

   

    我们发现是不可以的。因为写锁是排它锁,也就是只可以当前线程操作锁住的表,其他用户线程需要等到解锁之后才可以操作该表。

   

 3.总结

  1) 甲对表A加了读锁

     1.甲对表A可以执行读(查询)操作,但不可以执行写(增删改)操作

     2.甲对其他表不可以执行读写(增删改查)操作

     3.乙对表A可以执行读(查询)操作,但不可以执行写(增删改)操作

     4.乙对其他表可以执行读写(增删改查)操作

   

  2) 甲对表A加了写锁

     1.甲对表A可以执行读写(增删改查)操作

     2.甲对其他表不可以执行读写(增删改查)操作

     3.乙对表A不可以执行读写(增删改查)操作

     4.乙对其他表可以执行读写(增删改查)操作

   

四、MyISAM存储引擎中锁特点

  1.执行select语句的时候,会自动给涉及的表加上表锁,在执行更新操作时,会自动给表加上写锁

  2.MyISAM存储引擎比较适合作为以查询为主的表存储引擎,不适合写为主的表存储引擎,因为加写锁后,是锁住整个表,其他用户线程不能做任何操作,

   这样会导致大量用户线程阻塞的情况。

五、表锁的状态查询

  1.查询指令

   show status like 'table_lock%';

   

   说明:

   Table_locks_immediate:表示可以立即获取锁的查询次数,每获取一次锁就增加1

   Table_locks_waited:锁等待的次数(重要,如果这个值的大,则说明锁表的次数多,需要优化,通过 show open tables,查看哪些表锁了,然后分析为什么会锁)。

MySQL性能优化(七·上)-- 锁机制 之 表锁的更多相关文章

  1. MySQL性能优化(七):其它优化

    原文:MySQL性能优化(七):其它优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/v ...

  2. mysql锁机制之表锁(三)

    顾名思义,表锁就是一锁锁一整张表,在表被锁定期间,其他事务不能对该表进行操作,必须等当前表的锁被释放后才能进行操作.表锁响应的是非索引字段,即全表扫描,全表扫描时锁定整张表,sql语句可以通过执行计划 ...

  3. mysql 性能优化索引、缓存、分表、分布式实现方式。

    系统针对5000台终端测试结果 索引 目标:优化查询速度3秒以内 需要优化.尽量避免使用select * 来查询对象.使用到哪些属性值就查询出哪些使用即可 首页页面: 设备-组织查询 优化 避免使用s ...

  4. redmine在linux上的mysql性能优化方法与问题排查方案

    iredmine的linux服务器mysql性能优化方法与问题排查方案     问题定位:   客户端工具: 1. 浏览器inspect-tool的network timing工具分析   2. 浏览 ...

  5. 再谈mysql锁机制及原理—锁的诠释

    加锁是实现数据库并发控制的一个非常重要的技术.当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁.加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更 ...

  6. MySQL性能优化总结

    一.MySQL的主要适用场景 1.Web网站系统 2.日志记录系统 3.数据仓库系统 4.嵌入式系统 二.MySQL架构图: 三.MySQL存储引擎概述 1)MyISAM存储引擎 MyISAM存储引擎 ...

  7. MYSQL性能优化的最佳20+条经验

    MYSQL性能优化的最佳20+条经验 2009年11月27日 陈皓 评论 148 条评论  131,702 人阅读 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数 ...

  8. mysql 性能优化方案

    网 上有不少MySQL 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果 ...

  9. mysql 性能优化方案1

    网 上有不少mysql 性能优化方案,不过,mysql的优化同sql server相比,更为麻烦与复杂,同样的设置,在不同的环境下 ,由于内存,访问量,读写频率,数据差异等等情况,可能会出现不同的结果 ...

随机推荐

  1. 采用Filter的方法解决Servlet的编码问题

    这样比你自己在Servlet代码中硬编码request.setCharacterEncoding, response.setCharacterEncoding方便多了 总之,如果你添加了这个filte ...

  2. Java 命令行运行java程序,出现“找不到或无法加载主类 ”的注意事项

    引用:http://blog.chinaunix.net/uid-27106528-id-5209914.html 要在CMD命令行中使用java 运行java程序,关于出现 “找不到或无法加载主类 ...

  3. 【WPF】设置ListBox容器Item的流式布局

    需求:像下图那样显示把一组内容装入ListBox中显示.要求用WrapPanel横向布局,顺序如图中的数字. 问题:ListBox默认的布局是从上往下单列的,所以需要设置布局. <ListBox ...

  4. 【C#】解析XML

    最近在尝试用WPF搞点桌面小应用. C#中使用System.Xml.XmlDocument类对XML文件进行操作. 文档详情如下: https://msdn.microsoft.com/en-us/l ...

  5. C语言 · 五次方数

    算法提高 五次方数   时间限制:1.0s   内存限制:256.0MB      问题描述 对一个数十进制表示时的每一位数字乘五次方再求和,会得到一个数的五次方数 例如:1024的五次方数为1+0+ ...

  6. pip下载保存Python包,pip离线安装

    新版pip下载安装包命令: pip download  -r requirements.txt  -d  /tmp/paks/ 在linux下       1.下载指定的包到指定文件夹.       ...

  7. [转]Python Web部署方式总结

    学过PHP的都了解,php的正式环境部署非常简单,改几个文件就OK,用FastCgi方式也是分分钟的事情.相比起来,Python在web应用上的部署就繁杂的多,主要是工具繁多,主流服务器支持不足,在了 ...

  8. hdu 1595 find the longest of the shortest(dijstra + 枚举)

    http://acm.hdu.edu.cn/showproblem.php?pid=1595 大致题意: 给一个图.让输出从中删除随意一条边后所得最短路径中最长的. . 思路: 直接枚举每条边想必是不 ...

  9. [oracle] 安装卸载及常见问题

    (1)安装oracle10g备注: ① 检查安装版本是否复合安装主机的硬件要求,避免版本不兼容.如64位的oracle就不能在x86的机器上运行安装. ② 检查安装主机是否满足oracle的硬件要求, ...

  10. Hbase Rowkey设计

    转自:http://www.bcmeng.com/hbase-rowkey/ 建立Schema Hbase 模式建立或更新可以通过 Hbase shell 工具或者使用Hbase Java API 中 ...