`actor_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(16) NOT NULL DEFAULT '',
`password` varchar(16) NOT NULL DEFAULT '',
PRIMARY KEY (`actor_id`),
KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
insert into actor(name,password) values('cat01','1234567');
insert into actor(name,password) values('cat02','1234567');
insert into actor(name,password) values('ddddd','1234567');
insert into actor(name,password) values('aaaaa','1234567');
insert into actor(name,password) values('zzz','1234567');
.....
mysql> select * from actor;
+----------+-------+----------+
| actor_id | name | password |
+----------+-------+----------+
| 1 | cat01 | 1234567 |
| 2 | cat02 | 1234567 |
| 3 | ddddd | 1234567 |
| 4 | aaaaa | 1234567 |
| 5 | xfd | 1234567 |
| 6 | cat02 | 1234567 |
| 7 | ddddd | 1234567 |
| 8 | aaaaa | 1234567 |
| 9 | xfd | 1234567 |
| 10 | cat02 | 1234567 |
| 11 | ddddd | 1234567 |
| 12 | aaaaa | 1234567 |
| 13 | xfd | 1234567 |
| 14 | zzz | 1234567 |
+----------+-------+----------+
14 rows in set (0.00 sec)
session1:
SET AUTOCOMMIT=0;
BEGIN;
SELECT actor_id FROM actor WHERE actor_id < 4
AND actor_id <> 1 FOR UPDATE;
然后会把session 2的如下sql
SET AUTOCOMMIT=0;
BEGIN;
SELECT actor_id FROM actor WHERE actor_id = 1 FOR UPDATE; --wait
SELECT actor_id FROM actor WHERE actor_id = 4 FOR UPDATE; --wait
SELECT actor_id FROM actor WHERE actor_id = 5 FOR UPDATE; good
SELECT actor_id FROM actor WHERE name = 'aaaaa' FOR UPDATE; --wait
SELECT actor_id FROM actor WHERE name = 'zzz' FOR UPDATE; --good
delete from actor WHERE actor_id = 5; --good
锁住的记录是 id = 1, 2, 3, 4
##############
另外一种情况比较极端:
当表里的数据是
mysql> select * from actor;
+----------+-------+----------+
| actor_id | name | password |
+----------+-------+----------+
| 1 | cat01 | 1234567 |
| 2 | cat02 | 1234567 |
| 3 | ddddd | 1234567 |
| 4 | aaaaa | 1234567 |
| 5 | zzz | 1234567 |
| 6 | zzz | 1234567 |
+----------+-------+----------+
在session 1中执行
SET AUTOCOMMIT=0;
BEGIN;
SELECT * FROM actor WHERE actor_id < 4
AND actor_id <> 1 FOR UPDATE;
session 2中下面sql都会wait
SELECT actor_id FROM actor WHERE actor_id = 4 FOR UPDATE;
SELECT actor_id FROM actor WHERE actor_id = 5 FOR UPDATE;
SELECT actor_id FROM actor WHERE actor_id = 5 FOR UPDATE;
ID从1-6都被锁住了
Show innodb status\G
mysql> explain SELECT actor_id FROM actor WHERE actor_id < 4
-> AND actor_id <> 1 FOR UPDATE\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: actor
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 2
Extra: Using where; Using index
1 row in set (0.01 sec)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: actor
type: index --全索引扫描
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 6
Extra: Using where; Using index
1 row in set (0.00 sec)
This work is licensed under a CC A-S 4.0 International License.