转  InnoDB 行级锁

http://www.cnblogs.com/dongqingswt/archive/2013/03/28/2987367.html

分类: 数据库2013-03-13 16:40 1745人阅读 评论(0) 收藏 举报

nnoDB的行锁模式及加锁方法

InnoDB实现了以下两种类型的行锁。

 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。

 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。

另外,为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks),这两种意向锁都是表锁。

 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

上述锁模式的兼容情况具体如表20-6所示。

表20-6     InnoDB行锁模式兼容性列表

请求锁模式

 

   是否兼容

 

当前锁模式

X

IX

S

IS

X

冲突

冲突

冲突

冲突

IX

冲突

兼容

冲突

兼容

S

冲突

冲突

兼容

兼容

IS

冲突

兼容

兼容

兼容

如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。

意向锁是InnoDB自动加的,不需用户干预。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务可以通过以下语句显示给记录集加共享锁或排他锁。

·共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

·排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE。

用SELECT ... IN SHARE MODE获得共享锁,主要用在需要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操作。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT... FOR UPDATE方式获得排他锁。

在如表20-7所示的例子中,使用了SELECT ... IN SHARE MODE加锁后再更新记录,看看会出现什么情况,其中actor表的actor_id字段为主键。

表20-7           InnoDB存储引擎的共享锁例子

session_1

session_2

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select actor_id,first_name,last_name from actor where actor_id = 178;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select actor_id,first_name,last_name from actor where actor_id = 178;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

当前session对actor_id=178的记录加share mode 的共享锁:

mysql> select actor_id,first_name,last_name from actor where actor_id = 178 lock in share mode;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.01 sec)

其他session仍然可以查询记录,并也可以对该记录加share mode的共享锁:

mysql> select actor_id,first_name,last_name from actor where actor_id = 178 lock in share mode;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.01 sec)

当前session对锁定的记录进行更新操作,等待锁:

mysql> update actor set last_name = 'MONROE T' where actor_id = 178;

等待

其他session也对该记录进行更新操作,则会导致死锁退出:

mysql> update actor set last_name = 'MONROE T' where actor_id = 178;

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

获得锁后,可以成功更新:

mysql> update actor set last_name = 'MONROE T' where actor_id = 178;

Query OK, 1 row affected (17.67 sec)

Rows matched: 1  Changed: 1 Warnings: 0

当使用SELECT...FOR UPDATE加锁后再更新记录,出现如表20-8所示的情况。

表20-8             InnoDB存储引擎的排他锁例子

session_1

session_2

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select actor_id,first_name,last_name from actor where actor_id = 178;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

mysql> set autocommit = 0;

Query OK, 0 rows affected (0.00 sec)

mysql> select actor_id,first_name,last_name from actor where actor_id = 178;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

当前session对actor_id=178的记录加for update的共享锁:

mysql> select actor_id,first_name,last_name from actor where actor_id = 178 for update;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

其他session可以查询该记录,但是不能对该记录加共享锁,会等待获得锁:

mysql> select actor_id,first_name,last_name from actor where actor_id = 178;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE   |

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

1 row in set (0.00 sec)

mysql> select actor_id,first_name,last_name from actor where actor_id = 178 for update;

等待

当前session可以对锁定的记录进行更新操作,更新后释放锁:

mysql> update actor set last_name = 'MONROE T' where actor_id = 178;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1 Warnings: 0

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

其他session获得锁,得到其他session提交的记录:

mysql> select actor_id,first_name,last_name from actor where actor_id = 178 for update;

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

| actor_id | first_name | last_name |

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

| 178      | LISA       | MONROE T |

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

1 row in set (9.59 sec)

mysql 共享锁-排它锁的更多相关文章

  1. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  2. MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解

    锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或县城并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一 ...

  3. MySql共享锁和排它锁

    共享锁和排他锁 1.共享锁: 读锁.X锁,在查询时生效,多个事务在查询同一个数据时共享一把锁,但是不能作用于修改数据,在select语句后添加 lock in share mode : 2.排他锁:在 ...

  4. mysql共享锁与排它锁

    共享锁shared lock(也叫读锁read lock)又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁.这保证了其 ...

  5. mysql共享锁与排他锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  6. Mysql共享锁、排他锁、悲观锁、乐观锁

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...

  7. Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...

  8. 共享锁&排它锁 || 乐观锁&悲观索

    1.共享锁只用于表级,排他锁用于行级. 2.加了共享锁的对象,可以继续加共享锁,不能再加排他锁.加了排他锁后,不能再加任何锁. 3.比如一个DML操作,就要对受影响的行加排他锁,这样就不允许再加别的锁 ...

  9. MySQL/InnoDB中,乐观锁、悲观锁、共享锁、排它锁、行锁、表锁、死锁概念的理解

    文章出处:https://www.souyunku.com/2018/07/30/mysql/?utm_source=tuicool&utm_medium=referral MySQL/Inn ...

随机推荐

  1. 64位CentOS 6.4下安装wine(32位)

    1. 到http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/epel-release.html下载epel-release-6-8.noarc ...

  2. Python生成验证码

    #!/usr/bin/env python #coding:utf8 import random #方法1: str_code='zxcvbnmasdfghjklqwertyuiopZXCVBNMAS ...

  3. 别让emacs损伤你的小母指

    刚接触emacs时感觉,这东西怎么这么难用,还说是编辑器的神,我去. 写个代码跟挫游戏机手柄似的,关键是还这么难挫,平时用的最多的左ctrl键,这么难按,可怜的我的小母指(Petyr Baelish) ...

  4. 监听EditText

    0.得到焦点的时候,作一些处理 public class AbcActivity extends Activity implements OnFocusChangeListener{ @Overrid ...

  5. js中arguments的作用

    在javascript函数体内,标识符arguments具有特殊含义.它是调用对象的一个特殊属性,用来引用Arguments对象. Arugments对象就像数组,注意这里只是像并不是哈. javas ...

  6. 配置spring的事务管理

    网上看到过很多关于spring事务管理的东西,但是原创的并不多,如果你的运气好能看到那些原创的文章恭喜你,因为我看到的不多,但一些原创的文 章里面枝叶太多,因为那些高手直接把自己的代码拷过来,所以说无 ...

  7. Android水平(横向)翻页列表,类似水平GridVIew

    Android水平(横向)翻页列表,类似于水平方向的GridView,行列自定义,但要翻页切换,考虑加载性能,当Item数据很多时加载和翻页要流畅,翻页时要有动画效果,效果图如下: 实现方式: 1:翻 ...

  8. mybatis generator自动生成 实体类, sqlmap配置文件 详细介绍

    我使用的是Eclipse Luna 装了自己常用的插件, generator也是其中一个推荐下载 MyBatis_Generator_1.3.1.zip离线安装包 <?xml version=& ...

  9. ajax加php实现三级联动

    js代码 <script type="text/javascript">    function get_next(t,pid){  //当前元素的id,当前optio ...

  10. 1047: [HAOI2007]理想的正方形 - BZOJ

    Description 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小.Input 第一行为3个整数,分别表示a,b,n的值第二行至第a ...