转  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. linux 学习笔记3

    ①find -name *.txt //查看当前目录所有文件 .txt 结尾文件 ②whereis *.txt   //查看.txt结尾文件   但不显示 .txt 打包:tar -cf a.tar ...

  2. 解决CxGrid Filter 后,通过 Dataset 循环时得出的结果与 Grid显示不同步的问题.

    // 方案1: 强制cxgrid 使用 dataset的 Filter GridMaster.DataController.Filter.AutoDataSetFilter := True; /// ...

  3. Spark小课堂Week4 从控制台看Spark逻辑结构

    Spark小课堂Week4 从控制台看Spark逻辑结构 层级关系: 从监控控制台,我们可以看到如下关系: 一个 Job 包含 n Stage 一个 Stage 包含 n Task Job0解决什么问 ...

  4. WPF简单的口算案例

    前几天在博客园,看到有博友利用Winform做了一个口算案例,于是我想把它移植在WPF程序中.Winform程序:http://www.cnblogs.com/ImYZF/p/3345452.html ...

  5. MySQL日期和时间函数

    WEEKDAY( date ) 返回date的星期索引( = 星期天 ) . mysql> select WEEKDAY( '1997-10-04 22:23:00' ) ; mysql> ...

  6. 【学习总结】整理一下int, NSInteger 等概念

    基本需要知道的 : unsigned : 没符号的 signed  : 有符号的 int : 整型 看看OC的定义 : #if __LP64__ || (TARGET_OS_EMBEDDED & ...

  7. python学习笔记11(函数二): 参数的传递、变量的作用域

    一.函数形参和实参的区别 形参全称是形式参数,在用def关键字定义函数时函数名后面括号里的变量称作为形式参数. 实参全称为实际参数,在调用函数时提供的值或者变量称作为实际参数. >>> ...

  8. 简单3d RPG游戏 之 004 攻击(二)

    人物和怪物的攻击都有CD冷却,在PlayerAttack脚本中添加成员 //冷却倒计时 public float attackTimer; //CD冷却时间 public float coolDown ...

  9. hadoop 错误处理机制

    hadoop 错误处理机制 1.硬件故障 硬件故障是指jobtracker故障或TaskTracker 故障 jobtracker是单点,若发生故障,目前hadoop 还无法处理,唯有选择最牢靠的硬件 ...

  10. EasyUI Datagrid 取编辑修改后的内容

    <script type="text/javascript"> $(function () { $('#tt').datagrid({ iconCls: 'icon-e ...