一:概述

相对其他数据库而言,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. HTTPS协议入门

    目录什么是https?https的利与弊?https的原理和流程?什么是证书/CA证书?什么是单向SSL认证与双向SSL认证?网站如何实现https?网站实现https的一些补充说明参考网页 一.什么 ...

  3. socket套接字编程

    一.概述 1.socket是一种进程间通信方式,既可以用于一台机器,也可以用于网络.常用语C/S模型. 2.可以跨越Windows和Linux操作系统,可以跨越不同语言. 3.注意网络字节序和主机字节 ...

  4. css样式表的选择器与分类

    css 样式表的作用: 主要用于结构,样式与行为,CSS主要的作用就是美化网页的一个语言,它的特点: 1.结构与样式分离的方式,便于后期维护与改版; 2.样式定义精确到像素的级别; css样式表的结构 ...

  5. Angular JS从入门基础 mvc三层架构 常用指令

    Angular JS从入门基础  mvc模型 常用指令 ★ 最近一直在复习AngularJS,它是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心 ...

  6. 关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签

    public string getHtml(string Url, string type = "UTF-8") { try { System.Net.WebRequest wRe ...

  7. loadrunner11的移动端性能测试之脚本录制

    以前使用LR11录制过一个app的登录操作,这里记录一下 测试准备 硬件要求 1,  负载测试机一台(内存8G以上,cpu 1.5GHZ以上,存储空间20G以上)或两台以上(控制机和多个负载机). 2 ...

  8. ubuntu16.04-x64系统中Jexus web server部署.NetCore和端口分析引发的猜想!

    您有这样的牢骚么? 有一周没更新博客了,简单说下在干什么吧:主要是公司安排对接某旅游大公司的接口,接口数量倒也就10个左右,对接完后还需要加入到业务系统中和App端,因此还是需要花点时间的:时间上来说 ...

  9. Python模块之ConfigParser - 读写配置文件

    Python 标准库的 ConfigParser 模块提供一套 API 来读取和操作配置文件. 配置文件的格式 a) 配置文件中包含一个或多个 section, 每个 section 有自己的 opt ...

  10. EF架构~codeFirst从初始化到数据库迁移

    一些介绍 CodeFirst是EntityFrameworks的一种开发模式,即代码优先,它以业务代码为主,通过代码来生成数据库,并且加上migration的强大数据表比对功能来生成数据库版本,让程序 ...