mysql select for update, row lock, table lock

mysql select for update, row lock, table lock

一些前置条件

打开连个控制台模拟

mysql> show create table table_test;
| Table      | Create Table                                                                
| table_test | CREATE TABLE `table_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_index` int(11) DEFAULT '0',
  `id_no_index` int(11) DEFAULT '0',
  `common` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `index_id_index` (`id_index`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 |
mysql> select * from table_test;
+----+----------+-------------+--------+
| id | id_index | id_no_index | common |
+----+----------+-------------+--------+
|  1 |        0 |           0 |      1 |
|  2 |        0 |           0 |      2 |
|  3 |        0 |           0 |      3 |
|  4 |        0 |           0 |      4 |
|  5 |        0 |           0 |      5 |
|  6 |        1 |           1 |      5 |
|  7 |        1 |           1 |      6 |
|  8 |        1 |           1 |      7 |
|  9 |        1 |           1 |      8 |
| 10 |        1 |           1 |      9 |
+----+----------+-------------+--------+
10 rows in set (0.00 sec)
mysql> set autocommit = 0;

索引字段

session1

mysql> begin;
mysql> select * from table_test where id_index=1 for update;

session2

mysql> select * from table_test where id_index=0 for update;

 正常执行

mysql> select * from table_test where id_index=1 for update;

阻塞,当session1执行 "commit" or "rollback" 释放锁,session2继续执行

结论:有索引的字段用row lock

无索引字段

session1

mysql> begin;
mysql> select * from table_test where id_no_index=1 for update;

session2

select * from table_test where id_no_index=0 for update;

此时会阻塞,当session1执行 "commit" or "rollback" 释放锁,session2继续执行

结论:无索引的字段用table lock

范围条件

mysql> select * from table_test where id>8 for update;
+----+----------+-------------+--------+
| id | id_index | id_no_index | common |
+----+----------+-------------+--------+
|  9 |        1 |           1 |      8 |
| 10 |        1 |           1 |      9 |
+----+----------+-------------+--------+

mysql 会将这两条记录加锁

也会对大于10的加锁,这种锁机制就是所谓的间隙锁(Next-Key 锁)

session1

mysql> begin;
mysql> select * from table_test where id_index>8 for update;

session2

mysql> select * from table_test where id_index<8 for update;

正常执行

mysql> insert into table_test(id,id_index,id_no_index,common) values (11,1,1,10);

此时会阻塞,当session1执行 "commit" or "rollback" 释放锁,session2继续执行

 InnoDB行锁和表锁的分析

http://haicang.blog.51cto.com/2590303/1085388

猜你喜欢

转载自shifulong.iteye.com/blog/2252476