文档章节

InnoDB行锁特点

我爱祥子
 我爱祥子
发布于 2015/04/20 12:34
字数 606
阅读 8
收藏 0

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQLORACLE不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能。下面我们通过一些实际例子,来加以说明。

1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁。

下面的例子中,开始tab_no_index表没有索引:

    mysql> create table tab_no_index(id int,name varchar(10)) engine=innodb;

    Query OK, 0 rows affected (0.15 sec)

    mysql> insert into tab_no_index values(1,'1'),(2,'2'),(3,'3'),(4,'4');

    Query OK, 4 rows affected (0.00 sec)

    Records: 4 Duplicates: 0 Warnings: 0

                     InnoDB存储引擎的表在不使用索引时使用表锁例子                   

session_1

session_2

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_no_index where id = 1 ;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_no_index where id = 2 ;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_no_index where id = 1 for update;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_no_index where id = 2 for update;

等待

上面的例子中,看起来session_1只给一行加了排他锁,但session_2在请求其他行的排他锁时,却出现了锁等待!原因就是在没有索引的情况下,InnoDB只能使用表锁。当我们给其增加一个索引后,InnoDB就只锁定了符合条件的行,如下例所示:

创建tab_with_index表,id字段有普通索引

    mysql> create table tab_with_index(id int,name varchar(10)) engine=innodb;

    Query OK, 0 rows affected (0.15 sec)

    mysql> alter table tab_with_index add index id(id);

    Query OK, 4 rows affected (0.24 sec)

    Records: 4 Duplicates: 0 Warnings: 0

                                   InnoDB存储引擎的表在使用索引时使用行锁例子

session_1

session_2

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_with_index where id = 1 ;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tab_with_index where id = 2 ;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_with_index where id = 1 for update;

+------+------+

| id   | name |

+------+------+

| 1    | 1    |

+------+------+

1 row in set (0.00 sec)

mysql> select * from tab_with_index where id = 2 for update;

+------+------+

| id   | name |

+------+------+

| 2    | 2    |

+------+------+

1 row in set (0.00 sec)

© 著作权归作者所有

共有 人打赏支持
我爱祥子
粉丝 2
博文 57
码字总数 27333
作品 0
北碚
高级程序员
SQL优化之一则MySQL中的DELETE、UPDATE 子查询的锁机制失效案例

前言 开发与维护人员避免不了与 in/exists、not in/not exists 子查询打交道,接触过的人可能知道 in/exists、not in/not exists 相关子查询会使 SELECT 查询变慢,没有 join 连接效率,却不...

全部原谅
07/27
0
0
mysql 开发进阶篇系列 6 锁问题

一.概述   在数据库中,数据是属于共享资源,为了保证并发访问的一致性,有效性,产生了锁。接下来重点讨论mysql锁机制的特点,常见的锁问题,以及解决mysql锁问题的一些方法或建议。 相比...

花阴偷移
07/23
0
0
MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇

Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/JavaGuide 一 MyISAM 1.1 MyISAM简介 MyISAM是MySQL的默认数据库引擎(5.5版...

snailclimb
06/05
0
0
MyISAM和InnoDB区别详解

MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良。虽然性能极佳,但却有一个缺点:不支持事务处理(transacti...

xiaocao13140
04/20
0
0
Mysql InnoDB 和 MyISAM 的区别

InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。 基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强...

夕阳红树林
2012/06/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

线性一致性和 Raft

作者:沈泰宁 在讨论分布式系统时,共识算法(Consensus algorithm)和一致性(Consistency)通常是讨论热点,两者的联系很微妙,很容易搞混。一些常见的误解:使用了 Raft [0] 或者 paxos ...

TiDB
18分钟前
0
0
兄弟连区块链教程以太坊源码分析core-state-process源码分析

## StateTransition状态转换模型 /* The State Transitioning Model 状态转换模型 A state transition is a change made when a transaction is applied to the cu......

兄弟连区块链入门教程
20分钟前
0
0
linear-gradient渐变中的参数

在看张鑫旭的博客 遇到渐变数值后面带参数不太理解 @supports (-webkit-mask: none) or (mask: none) { .box { border: none; background: linear-gradient(to bottom, #34538...

红羊在厦门
21分钟前
0
0
Python yagmail模块自动发邮件

Python发邮件yagmail模块 import yagmail#连接服务器yag=yagmail.SMTP('xx@163.com','yy','smtp.163.com')#邮箱正文contents=["test","email send"]#发送邮件#yag.send('...

小白兔_球球
22分钟前
1
0
pada mysql

CREATE SCHEMA `exchange` DEFAULT CHARACTER SET utf8mb4 ;

qwfys
31分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部