MySQL的锁机制,表锁、行锁
来源:互联网 发布:狸窝网络视频下载器 编辑:程序博客网 时间:2024/06/12 20:32
成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。
锁
一、MySQL锁概述
相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
MySQL这3种锁的特性可大致归纳如下。
开销、加锁速度、死锁、粒度、并发性能
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
从上述的特点来看,很难笼统的说哪种锁更好,我觉得每一种锁既然存在都有其优点的,那我们应该如何选择锁方式呢?
究竟哪种锁适合自己,要根据当前的使用场景以及业务来决定的,仅从锁的角度来说: 1、表级锁更加适合于以查询为主,只有少量按索引条件更新数据的应用。 2、行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理系统
二、MyISAM表锁
MyISAM存储引擎只支持表锁,这也是MySQL开始几个版本中唯一支持的锁类型。随着应用对事务完整性和并发性要求的不断提高,MySQL才开始开发基于事务的存储引擎,后来慢慢出现了支持页锁的BDB存储引擎和支持行锁的InnoDB存储引擎。但是MyISAM的表锁依然是使用最为广泛的锁类型。下面详细介绍MyISAM表锁的使用。
1、查询表级锁争用情况
可以通过检查table_locks_waited和table_locks_immediate状态变量来分析系统上的表锁定争夺:
mysql> show status like ‘table%’;
+———————–+——-+
| Variable_name | Value |
+———————–+——-+
| Table_locks_immediate | 206 |
| Table_locks_waited | 0 |
+———————–+——-+
2 rows in set (0.00 sec)
注意:如果Table_locks_waited的值比较高,则说明存在着较严重的表级锁争用情况。
Table_locks_immediate表示立即释放表锁数,Table_locks_waited表示需要等待的表锁数,
2、MySQL表级锁的锁模式
MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。锁模式的兼容性如下所示。
可 见,对MyISAM表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;对 MyISAM表的写操作,则会阻塞其他用户对同一表的读和写操作;MyISAM表的读操作与写操作之间,以及写操作之间是串行的!当一个线程获得对一个表的写锁后,只有持有锁的线程可以对表进行更新操作。其他线程的读、写操作都会等待,直到锁被释放为止。
以上内容都是通过官方资料以及先辈总结出来的结果,那么事实是否真的是这样呢?接下来就亲自动手试一试,看看结果如何?
首先创建一个测试的表,插入一些简单的数据,如下:
+——-+———————————————————————-
| Table | Create Table
+——-+———————————————————————-
| test1 | CREATE TABLE test1
(
id
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(32) NOT NULL DEFAULT ” COMMENT ‘名称’,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1 |
+——-+———————————————————————-
1 row in set (0.04 sec)
同时打开两个mysql线程,模拟并发场景:
结论:MyISAM表:
1、加读锁,当前session可以正常进行读操作,不能进行更新和写操作,其他session只能进行读操作,不能进行写操作。
2、加写锁,当前session可以正常进行读、写操作,其他session不能进行读与写操作。
3、在加锁时,如果显示的指明是要增加读锁,那么在解锁之前,只能进行读操作,不能执行写操作。
4、如果一次Sql语句要操作的表以别名的方式多次出现,那么就要在加锁时都指明要加锁的表的别名。
5、MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0、1或2。由于读锁和写锁互斥,那么在调度过程中,默认情况下,MySql会本着写锁优先的原则。可以通过low-priority-updates来设置。
加锁以及解锁命令:
锁定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},…]
解锁表:UNLOCK TABLES
问题:
1、unlock tables; 命令一旦执行是所有的表都会解锁吗? 答案:不是,unlock只对当前session添加的读、写锁等生效,对其他的是不影响的。当前线程关闭时,自动退出封闭空间,释放所有表锁,无论有没有执行 unlock tables2、两个线程,其中一个为test1表添加读锁,另外一个线程可以为该表添加写锁吗? 答案:不能,一个线程添加了锁以后,另外一个线程只能排队等待,不能同时为该表添加写锁。
3、代码中如何来实现呢?如下:
/** * 锁表 * @param string $table 表名 * @param int $type 读锁1还是写锁2 */ public function lock( $table, $type = 1 ) { $type = ( $type == 1 ) ? 'READ' : 'WRITE'; $this->query( "LOCK TABLE `$table` $type" ); } /** * 解锁 */ public function unlock() { $this->query( "UNLOCK TABLES" ); }
以上内容参考:
http://yypiao.iteye.com/blog/2295218
http://blog.csdn.net/u013063153/article/details/53432468
http://xu20cn.blog.51cto.com/274020/72574
- MySQL的锁机制,表锁、行锁
- mysql的锁机制
- mysql的锁机制
- Mysql的锁机制
- mysql的锁机制
- MySQL的锁机制
- mysql的锁机制
- MySQL的锁机制
- mysql的锁机制
- mysql的锁机制
- Mysql的行锁机制
- MySQL数据库的锁机制
- Mysql的锁机制解读
- MySQL的InnoDB锁机制
- Mysql锁机制的理解
- Mysql的锁机制解读
- mysql的锁机制总结
- Mysql的锁机制解读
- android IPC学习(二) 创建多进程
- linux下aliax的作用
- SpringAop中使用@AspectJ注解
- angularJS自定义指令详解
- 获取某一天一周内所有的日期
- MySQL的锁机制,表锁、行锁
- 响应式网站布局学习
- python在不同层级目录import模块的方法 作者:运维之路 字体:[增加 减小] 类型:转载 时间:2016-01-31 我要评论 这篇文章主要介绍了python 在不同层级目录import
- android面试题-ActivityRecord TaskRecord和ProcessRecord之间的关系
- javaWeb开发中为什么要使用框架
- react-navigation使用技巧
- //获取输入框的值
- 常见as报错信息记录
- 微信分享没有缩略图,描述