一:概述

相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);InnoDB存储引擎既支持行级锁( row-level locking),也支持表级锁,但默认情况下是采用行级锁。

MySQL主要的两种锁的特性可大致归纳如下:
 表级锁: 开销小,加锁快;不会出现死锁(因为MyISAM会一次性获得SQL所需的全部锁);锁定粒度大,发生锁冲突的概率最高,并发度最低。
 行级锁: 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

考虑上述特点,表级锁使用与并发性不高,以查询为主,少量更新的应用,比如小型的web应用;而行级锁适用于高并发环境下,对事务完整性要求较高的系统,如在线事务处理系统。

二:MyISAM锁细述

(1). 锁模式

MySQL的表级锁有两种模式: 表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。

(2).  如何加锁

当MyISAM在执行查询语句时,会自动给涉及到表加读锁,在执行更新操作时,会加写锁。当然用户也可以用LOCK TABLE 去显式的加锁。显式的加锁一般是应用于:需要在一个时间点实现多个表的一致性读取,不然的话,可能读第一个表时,其他表由于还没进行读操作,没有自动加锁,可能数据会发生改变。并且显示加锁后只能访问加锁的表,不能访问其他表。

(3). 并发插入

MyISAM存储引擎有个系统变量 concurrent_insert,专门用来控制并发插入的行为,可以取 0 , 1 , 2。

0表示不允许并发插入,1表示表中间没有删除的行时可以在表末尾插入,2表示总是可以插入。

一般如果对并发要求比较高的情况下,可以设置为2,总是可以插入,然后定期在数据库空闲时间对表进行optimize。

(4). 锁的调度

需要注意的是,其中读操作不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;并且当写锁和读锁同时被申请时,优先获得写锁,这也这正是表级锁发生锁冲突概率最高的原因,因为写锁可能会一直阻塞读锁,所以不适合有大量写操作的环境下工作。这一问题可以通过设置low-priority-updates这一启动参数来降低写的优先级。
虽然写锁优先于读锁获取,但是长时间的查询操作也可能会让写操作饿死,所以尽量避免一条SQL语句执行所有的查询,应该进行必要的分解。

三:InnoDB锁细述

由于InnoDB支持事务,并默认是使用行级锁,所以InnoDB的锁问题和MyISAM锁问题还是有蛮大差别的。

(1). 锁模式

共享锁(S)和排他锁(X),分别类似于MyISAM的读锁和写锁。对于 UPDATE、 DELETE 和 INSERT 语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通 SELECT 语句,InnoDB不会加任何锁。

(2). 如何加锁

可以显式的加锁,用lock in share mode 显式的加共享锁,用 for update 显式的加排他锁。

需要注意的是,如果线程A加了共享锁后,线程B对同一个表加了共享锁,那么两个线程需要进行更新操作时会产生死锁。所以,进行更新操作时最好加排他锁。

(3). InnoDB行锁的实现方式——索引加锁

这一点与Oracle不同,所以这也意味着(重要):1. 只有通过索引条件检索数据时,InnoDB才会使用行级锁,否则会使用表级锁。 2. 即使是访问不同行的记录,如果使用的是相同的索引键,会发生锁冲突。 3. 如果数据表建有多个索引时,可以通过不同的索引锁定不同的行。

(4). 间隙锁

InnoDB支持事务,为了满足隔离级别的要求,InnoDB有个间隙锁,当使用范围查找时,InnoDB会给满足key范围要求,但实际并不存在的记录加锁。例如:select * from user where id > 100 for updata 会给ID>100的记录加排他锁,满足这个范围,但不存在的记录,会加间隙锁,这样可以避免幻读,避免读取的时候插入满足条件的记录。

(5). 隔离级别与锁

一般来说,隔离级别越高,加锁就越严格。这样,产生锁冲突的概率就越大,一般实际应用中,通过优化应用逻辑,选用 可提交读 级别就够了。对于一些确实需要更高隔离级别的事务,再通过set session transaction isolation level+"级别" 来动态改变满足需求。

四:死锁

MyISAM是没有死锁问题的,因为他会一次性获得所有的锁。InnoDB发生死锁后一般能自动检测到,并使一个事务释放锁并回退,另一个事务获得锁,继续完成事务。

在应用中,可以通过如下方式来尽可能的避免死锁:

(1) 如果不同的程序会并发的存取多个表,应尽量约定以相同的顺序来访问表,这样可以大大降低产生死锁的机会。

(2) 在程序以批量方式处理数据时,如果事先对数据排序,保证每个线程按固定的顺序来处理记录,也可以大大的降低出现死锁的可能。

MySQL学习笔记(五):MySQL表级锁和行级锁的更多相关文章

  1. 吴裕雄--天生自然MySQL学习笔记:MySQL 安装

    所有平台的 MySQL 下载地址为: MySQL 下载:https://dev.mysql.com/downloads/mysql/ 注意:安装过程我们需要通过开启管理员权限来安装,否则会由于权限不足 ...

  2. 吴裕雄--天生自然MySQL学习笔记:MySQL 运算符

    要介绍 MySQL 的运算符及运算符的优先级. MySQL 主要有以下几种运算符: 算术运算符 比较运算符 逻辑运算符 位运算符 算术运算符 MySQL 支持的算术运算符包括: 在除法运算和模运算中, ...

  3. 吴裕雄--天生自然MySQL学习笔记:MySQL 导入数据

    1.mysql 命令导入 使用 mysql 命令导入语法格式为: mysql -u用户名 -p密码 < 要导入的数据库数据(runoob.sql) 实例: # mysql -uroot -p12 ...

  4. 吴裕雄--天生自然MySQL学习笔记:MySQL 处理重复数据

    有些 MySQL 数据表中可能存在重复的记录,有些情况允许重复数据的存在,但有时候我们也需要删除这些重复的数据. 防止表中出现重复数据 可以在 MySQL 数据表中设置指定的字段为 PRIMARY K ...

  5. 吴裕雄--天生自然MySQL学习笔记:MySQL 临时表

    MySQL 临时表在我们需要保存一些临时数据时是非常有用的.临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间. MySQL临时表只在当前连接可见,如果使用PHP脚本来创建My ...

  6. 吴裕雄--天生自然MySQL学习笔记:MySQL 事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成 ...

  7. 吴裕雄--天生自然MySQL学习笔记:MySQL GROUP BY 语句

    GROUP BY 语句根据一个或多个列对结果集进行分组. 在分组的列上我们可以使用 COUNT, SUM, AVG,等函数. GROUP BY 语法 SELECT column_name, funct ...

  8. 吴裕雄--天生自然MySQL学习笔记:MySQL UNION 操作符

    MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中.多个 SELECT 语句会删除重复的数据. 语法 MySQL UNION 操作符语法格式: SELECT ...

  9. 吴裕雄--天生自然MySQL学习笔记:MySQL 管理

    启动及关闭 MySQL 服务器 Windows 系统下 在 Windows 系统下,打开命令窗口(cmd),进入 MySQL 安装目录的 bin 目录. 启动: cd c:/mysql/bin mys ...

随机推荐

  1. 夜神模拟器与HBuilder连接/cmd运行提示符/执行夜神模拟器命令/执行HBuilder命令

    第一步:启动HBuilder和夜神模拟器 第二步:通过运行电脑命令CMD进入(电脑运行命令的快捷键是:windows键+R2.Ctrl键与Alt键之间的那个键就是windows键或者点击左下角开始图标 ...

  2. 每天一个JS 小demo之新建文件夹。主要知识点:DOM方法的综合运用

    <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"& ...

  3. 12.ThreadPoolExecutor线程池原理及其execute方法

    jdk1.7.0_79  对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任 ...

  4. 破解 Adobe 系列的最佳方法,手把手教

    此方法是个人认为最方便的而且最安全的方法(可以避免下载到可能捆绑病毒的破解版本) 1.首先到Adobe的官网上下载 Creative Cloud: 打开官网上creative cloud 的下载页面: ...

  5. NodeJS 实现手机短信验证 模块阿里大于

    1,NodeJS 安装阿里大于模块 切换到项目目录使用npm 安装阿里于模块 npm i node-alidayu --save 2,aliyu官网使用淘宝账户登录 登录阿里大于 https://do ...

  6. js中年份、月份下拉框

    <select id="year" style="width: 100px;"></select> <select id=&quo ...

  7. win7开启telnet客户端

  8. bc计算A股上市新股依次涨停股价

    几年的股市可谓惨不忍睹,不提也罢.唯有打新中签的时候,心里稍微有那么一点点的补偿,于是内心就YY可以30板吗,可以40板吗.于是就写了个连板的bc程序,每次中签的时候就运行一下,然后尽情的YY,然而每 ...

  9. php追加数组

    <?php //追加数组 array_merge_recursive()函数与array_merge()相同,可以将两个或多个数组合并在一起,形成一个联合的数组.两者之间的区别在于,当某个输入数 ...

  10. css之选择器总结

    首先我们来看下有哪些选择器??? 一.基础选择器: html标签选择器:通过html标签来选择元素. ①所有的html标签都可以当做选择器. ②无论标签藏多深都会被选中. ③选择的是所有的标签而不是某 ...