您的位置:首页 > 数据库 > MySQL

Mysql——锁问题

2016-05-14 21:59 513 查看
1、概述

不同的存储引擎支持不同的锁机制,MyISAM和MEMORY存储引擎采用的是表级锁;BDB存储引擎采用的是页面锁,也支持表级锁;InnoDB则即支持行级锁,也支持表级锁,默认是行级锁。

表级锁:开销小,加锁快;不会出现死锁;锁定粒度小,发生锁冲突的概率最高,并发度最低。

行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

2、MyISAM表锁

有两种模式:表共享读锁和表独占写锁。锁模式的兼容性如下表所示:

当前\是否兼容\请求锁读锁写锁
读锁
写锁
如何加表锁:

MyISAM在执行查询语句前,会自动给涉及的所有表加读锁,在执行更新(增删改)操作前,会自动给涉及的表加写锁,不需要用户显示加锁。注意,当用户在执行LOCK TABLES后,只能访问显示加锁的这些表,不能访问未加锁的表;同时,如果加的是读锁,那么只能执行查询操作,而不能执行更新操作。

并发插入:

MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。

为0:不允许并发插入。

为1:当MyISAM表中没有空洞(即表的中间没有被删除的行),则允许在一个进程读表的同时,另一个进程从表尾插入记录。

为2:无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。

当session_1获得了一个表的READ LOCAL锁,该线程可以对表进行查询操作,但不能对表进行更新操作;其他线程,虽然不能对表进行删除和更新操作,但可以对该表进行并发插入操作。

3、InnoDB锁问题

背景知识:

事务及其ACID属性。原子性、一致性、隔离性和持久性。

并发事务

更新丢失、脏读、不可重复读、幻读。

事务隔离级别

隔离级别\读取一致性及并发副作用读数据一致性脏读不可重复读幻读
未提交读最低级别,只能保证不读取物理上损坏的数据
已提交读语句级
可重复读事务级
可序列化最高级别,事务级
4、InnoDB实现了一下两种类型的行锁:

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

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

为了允许行锁和表锁共存,实现多粒度锁值,InnoDB还有两种内部使用的意向锁,都是表锁:

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

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

请求锁模式\是否兼容\当前锁模式XIXSIS
X冲突冲突冲突冲突
IX冲突兼容冲突兼容
S冲突冲突兼容兼容
IS冲突兼容兼容兼容
相关语句:

共享锁:select * from table_name where … lock in share mode;

排他锁:select * from table_name where … for update;

注意,在使用共享锁时,如果两个事务 获得共享锁时,都需要对该记录进行更新操作,则很有可能造死锁。因此,对于锁定行记录后需要进行更新操作的应用,应该使用SELECT…FOR UPDATE方式获得排他锁。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: