1、MYSQL常见的几种锁:
MySQL有三种锁的级别:页级、表级、行级。
MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking);
BDB存储引擎采用的是页面锁(page-level locking),但也支持表级锁;
InnoDB存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。
MySQL这3种锁的特性可大致归纳如下:
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
2. 什么情况下会造成死锁
死锁是指两个或多个事务在同一资源上互相占用,并请求加锁时,而导致的恶性循环现象。当多个事务以不同顺序试图加锁同一资源时,就会产生死锁。任何时间,多个事务同时加锁同一资源,一定产生死锁。
例如,设想下列两个事务同时处理test表:
表结构如下:
CREATE TABLE `test` (
`id` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
插入数据:
insert into `test` ( `id`, `name`) values ( '1', '1111')
insert into `test` ( `id`, `name`) values ( '2', '2222')
(1)打开第一个命令行
首先设置本次回话为不自动提交事务:
set autocommit=0;
查看是否关闭自动提交:
show VARIABLES like 'auto%';
查询加锁(悲观锁) :
select * from test where id=1 for update;
(2)打开第二个命令行:
首先设置本次回话为不自动提交事务:
set autocommit=0;
查看是否关闭自动提交:
show VARIABLES like 'auto%'
查询加锁(悲观锁) :
select * from test where id=2 for update;
(3) 窗口会一直转,等待第一个事务结束
最终提示:
(4)在第一个回话使用show processlist
可以看到第二次锁的时候一致等待第一次锁的释放。
(5)其他地方再去修改数据会提示
(6)在后台会看到很多进程的进程处于等待状态