转摘: MySQL详解--锁
原文 http://blog.csdn.net/xifeijian/article/details/20313977
背景知识
1.事务(Transaction)及其ACID属性
2.并发事务处理带来的问题
3.事务隔离级别
|
读数据一致性及允许的并发副作用
隔离级别
|
读数据一致性
|
脏读
|
不可重复读
|
幻读
|
|
未提交读(Read uncommitted)
|
最低级别,只能保证不读取物理上损坏的数据
|
是
|
是
|
是
|
|
已提交度(Read committed)
|
语句级
|
否
|
是
|
是
|
|
可重复读(Repeatable read)
|
事务级
|
否
|
否
|
是
|
|
可序列化(Serializable)
|
最高级别,事务级
|
否
|
否
|
否
|
获取InnoDB行锁争用情况
InnoDB的行锁模式及加锁方法
|
请求锁模式
是否兼容
当前锁模式
|
X
|
IX
|
S
|
IS
|
|
X
|
冲突
|
冲突
|
冲突
|
冲突
|
|
IX
|
冲突
|
兼容
|
冲突
|
兼容
|
|
S
|
冲突
|
冲突
|
兼容
|
兼容
|
|
IS
|
冲突
|
兼容
|
兼容
|
兼容
|
InnoDB行锁实现方式
|
session_1
|
session_2
|
|
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
|
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
|
|
mysql> select * from tab_with_index where id = 1 and name = '1' for update;
+------+------+
| id | name |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)
|
|
|
虽然session_2访问的是和session_1不同的记录,但是因为使用了相同的索引,所以需要等待锁:
mysql> select * from tab_with_index where id = 1 and name = '4' for update;
等待
|
|
session_1
|
session_2
|
|
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
|
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
|
|
mysql> select * from tab_with_index where id = 1 for update;
+------+------+
| id | name |
+------+------+
| 1 | 1 |
| 1 | 4 |
+------+------+
2 rows in set (0.00 sec)
|
|
|
Session_2使用name的索引访问记录,因为记录没有被索引,所以可以获得锁:
mysql> select * from tab_with_index where name = '2' for update;
+------+------+
| id | name |
+------+------+
| 2 | 2 |
+------+------+
1 row in set (0.00 sec)
|
|
|
由于访问的记录已经被session_1锁定,所以等待获得锁。:
mysql> select * from tab_with_index where name = '4' for update;
|
间隙锁(Next-Key锁)
|
session_1
|
session_2
|
|
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
|
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
|
|
当前session对不存在的记录加for update的锁:
mysql> select * from emp where empid = 102 for update;
Empty set (0.00 sec)
|
|
|
这时,如果其他session插入empid为102的记录(注意:这条记录并不存在),也会出现锁等待:
mysql>insert into emp(empid,...) values(102,...);
阻塞等待
|
|
|
Session_1 执行rollback:
mysql> rollback;
Query OK, 0 rows affected (13.04 sec)
|
|
|
由于其他session_1回退后释放了Next-Key锁,当前session可以获得锁并成功插入记录:
mysql>insert into emp(empid,...) values(102,...);
Query OK, 1 row affected (13.35 sec)
|
恢复和复制的需要,对InnoDB锁机制的影响
另 外,对于“insert into target_tab select * from source_tab where ...”和“create table new_tab ...select ... From source_tab where ...(CTAS)”这种SQL语句,用户并没有对source_tab做任何更新操作,但MySQL对这种SQL语句做了特别处理。
InnoDB在不同隔离级别下的一致性读及锁的差异
|
隔离级别
一致性读和锁
SQL
|
Read Uncommited
|
Read Commited
|
Repeatable Read
|
Serializable
|
|
|
SQL
|
条件
|
||||
|
select
|
相等
|
None locks
|
Consisten read/None lock
|
Consisten read/None lock
|
Share locks
|
|
范围
|
None locks
|
Consisten read/None lock
|
Consisten read/None lock
|
Share Next-Key
|
|
|
update
|
相等
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
Exclusive locks
|
|
范围
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
|
|
Insert
|
N/A
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
|
replace
|
无键冲突
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
|
键冲突
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
|
|
delete
|
相等
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
|
范围
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
exclusive next-key
|
|
|
Select ... from ... Lock in share mode
|
相等
|
Share locks
|
Share locks
|
Share locks
|
Share locks
|
|
范围
|
Share locks
|
Share locks
|
Share Next-Key
|
Share Next-Key
|
|
|
Select * from ... For update
|
相等
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
exclusive locks
|
|
范围
|
exclusive locks
|
Share locks
|
exclusive next-key
|
exclusive next-key
|
|
|
Insert into ... Select ...
(指源表锁)
|
innodb_locks_unsafe_for_binlog=off
|
Share Next-Key
|
Share Next-Key
|
Share Next-Key
|
Share Next-Key
|
|
innodb_locks_unsafe_for_binlog=on
|
None locks
|
Consisten read/None lock
|
Consisten read/None lock
|
Share Next-Key
|
|
|
create table ... Select ...
(指源表锁)
|
innodb_locks_unsafe_for_binlog=off
|
Share Next-Key
|
Share Next-Key
|
Share Next-Key
|
Share Next-Key
|
|
innodb_locks_unsafe_for_binlog=on
|
None locks
|
Consisten read/None lock
|
Consisten read/None lock
|
Share Next-Key
|
|
什么时候使用表锁
关于死锁
|
session_1
|
session_2
|
|
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from table_1 where where id=1 for update;
...
做一些其他处理...
|
mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from table_2 where id=1 for update;
...
|
|
select * from table_2 where id =1 for update;
因session_2已取得排他锁,等待
|
做一些其他处理...
|
|
mysql> select * from table_1 where where id=1 for update;
死锁
|
(4)前面讲过,在REPEATABLE-READ隔离级别下,如果两个线程同时对相同条件记录用SELECT...FOR UPDATE加排他锁,在没有符合该条件记录情况下,两个线程都会加锁成功。程序发现记录尚不存在,就试图插入一条新记录,如果两个线程都这么做,就会出 现死锁。这种情况下,将隔离级别改成READ COMMITTED,就可避免问题
对于这种情况,可以直接做插入操作,然后再捕获主键重异常,或者在遇到主键重错误时,总是执行ROLLBACK释放获得的排他锁
转摘: MySQL详解--锁的更多相关文章
- MySQL详解
MySQL详解 什么是数据库 # 用来存储数据的仓库 # 数据库可以在硬盘及内存中存储数据 # 数据库与文件存储数据区别 # 数据库本质也是通过文件来存储数据, 数据库的概念就是系统的管理存储数据的文 ...
- MySql详解(四)
MySql详解(四) MySql的DML操作 插入: 一.方式一 语法: insert into 表名(字段名,...) values(值,...); 特点: 1.要求值的类型和字段的类型要一致或兼容 ...
- MySql详解(一)
MySql详解(一) 作为一名Java开发人员,数据库的地位不用多说了.从大学时期的SqlServer,到现在最流行的MySql和Oracle.前者随着阿里巴巴的去IOE化,在互联网公司中的使用比例是 ...
- MySql详解(三)
MySql详解(三) 导入基础表 具体的SQL文件已经放入百度网盘,连接为:http://pan.baidu.com/s/1hseoVR2,后面的MySql内容都是按照这些基础表展开的. depart ...
- MySql详解(五)
MySql详解(五) MySql库的管理 一.创建库 create database [if not exists] 库名[ character set 字符集名]; 二.修改库 alter data ...
- MySql详解(七)
MySql详解(七) MySql视图 一.含义 mysql5.1版本出现的新特性,本身是一个虚拟表,它的数据来自于表,通过执行时动态生成. 好处: 1.简化sql语句 2.提高了sql的重用性 3.保 ...
- MySql详解(六)
MySql详解(六) MySql事务 一.含义 事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行 二.特点(ACID) A 原子性:一个事务是不可再分割的整体,要么都执 ...
- MySQL详解--锁,事务
http://www.cnblogs.com/jukan/p/5670950.html http://blog.csdn.net/xifeijian/article/details/20313977 ...
- MySQL详解--锁,事务(转)
锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数 ...
随机推荐
- KNN算法的实现
K近邻(KNN)算法简介 KNN是通过测量不同特征值之间的距离进行分类.它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其 ...
- 尝试去读SQLMAP源码(一)
本人python 小菜比 一枚.拜读业界典范~~ 阅读sqlmap 的版本是1.1.6,目前应该是最新版. sqlmap.py 脚本中 72~83 def modulePath(): "&q ...
- ssh-copy-id 拷贝用户秘钥
生成秘钥 ssh-keygen -t [rsa|dsa] 将会生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub 将 .pub 文件复制到B机器的 .ssh ...
- ASP.NET Core学习之五 EntityFrameworkCore
目的:运用EntityFrameworkCore ,使用codefirst开发 一.创建web项目 创建一个不进行身份验证的 ASP.NET Core Web Application (.NET ...
- 给Ubuntu系统清理垃圾
原文地址:https://blog.csdn.net/levon2018/article/details/81746613 1.清理下载的软件包 不过与你想象的可能有很大的不同,Ubuntu系统在运 ...
- 响应式bootstrap - demo
参考资料: bootstrap:http://www.bootcss.com/ 汤姆大叔的博客: <深入理解Bootstrap>http://item.jd.com/11462962.ht ...
- 帆软报表(finereport)单元格中各颜色标识的含义
帆软报表(finereport)单元格中,可根据单元格角标的颜色判断单元格进行的操作 过滤:单元格左下角黄色三角形 条件属性:单元格左上角红色三角形. 控件:单元格右侧中间的各种矩形. 左父格:单 ...
- SQL Server2016安装
VS2017已经发布10多天了,这几天正好要重新做系统.所以想着把SQL Server和VS都做一次升级.VS2017只需要下载一个安装包就可以进行在线安装.但是SQL Server2016安装时会碰 ...
- 2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算
2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算 经过第一阶段的学习,同学们已经熟悉了这门语言基本的用法.在一次又一次对着电脑编写并提交代码,进行练习的时候,有没有觉 ...
- 关于git 远程仓库密码一直输错的问题
解决方法, git 换地方使用后需要重新配置秘钥,一个钥匙开一个地方的门: 如果还不行, 在控制面板-用户账户-凭据管理-加添凭证,输入正确的账号密码:因为Windows的凭据管理器里面可能保存了你刚 ...