操作
|
session_1
|
session_2
|
结论
|
在一个session设置行锁
|
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+----+----------+
| id | name |
+----+----------+
| 1 | body1 |
| 2 | body2 |
| 3 | body3 |
| 4 | bodytest |
| 5 | body5 |
| 6 | body6 |
| 7 | body7 |
| 8 | body8aa |
| 9 | body9 |
| 10 | body10 |
| 11 | body11 |
| 12 | body12 |
| 13 | body13 |
| 18 | body18 |
| 19 | body19 |
+----+----------+
15 rows in set (0.00 sec)
mysql> select * from test1 where id=2 for update;
+----+-------+
| id | name |
+----+-------+
| 2 | body2 |
+----+-------+
1 row in set (0.00 sec)
|
mysql> update test1 set name = 'body2aaaa' where id=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>
|
session_1中设置行锁,在session_2中去更新数据,是无法更新的,并且报出
Lock wait timeout exceeded错误(此时并没有为该表添加任何索引)
|
commit后 |
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
|
mysql> update test1 set name = 'body2aaaa' where id=2;
Query OK, 1 row affected (7.37 sec)
Rows matched: 1 Changed: 1 Warnings: 0
|
session_1中commit后解除了表锁,session_2中更新数据操作自动运行成功
|
为test1表创建索引
|
mysql>
alter table test1 add index idx_id(id);
Query OK, 0 rows affected (0.26 sec)
Records: 0 Duplicates: 0 Warnings: 0
|
|
|
索引创建成功以后,在加行锁
|
mysql> select * from test1 where id = 2 for update;
+----+-----------+
| id | name |
+----+-----------+
| 2 | body2aaaa |
+----+-----------+
1 row in set (0.00 sec)
|
mysql> update test1 set name = 'body1aaaa' where id=1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update test1 set name = 'body2bbbb' where id=2;
一直处于等待状态
|
添加索引后,我们去锁定id=2的记录,在另外一个session中去更新id=1的数据是可以成功的说明行锁创建成功。
|
|
|
|
|
Innodb_row_lock_current_waits
|
当前等待的待锁定的行数
|
Innodb_row_lock_time
|
系统启动到现在、锁定的总时间长度
|
Innodb_row_lock_time_avg
|
每次平均锁定的时间
|
Innodb_row_lock_time_max
|
最长一次锁定时间
|
Innodb_row_lock_waits
|
系统启动到现在、总共锁定次数
|
操作
|
session_1
|
session_2
|
结论
|
查询两个表中的数据
|
mysql> select * from test1 order by id asc;
+----+-----------+
| id | name |
+----+-----------+
| 1 | body1aaaa |
| 2 | body2aaaa |
| 3 | body3 |
| 4 | bodytest |
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
| 9 | body9 |
| 10 | body10 |
| 11 | body11 |
| 12 | body12 |
| 13 | body13 |
| 18 | body18 |
| 19 | body19 |
+----+-----------+
15 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.04 sec)
|
mysql> select * from test1 order by id asc;
+----+-----------+
| id | name |
+----+-----------+
| 1 | body1aaaa |
| 2 | body2aaaa |
| 3 | body3 |
| 4 | bodytest |
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
| 9 | body9 |
| 10 | body10 |
| 11 | body11 |
| 12 | body12 |
| 13 | body13 |
| 18 | body18 |
| 19 | body19 |
+----+-----------+
15 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.04 sec)
|
结果一致
|
给字段name添加索引,以name为条件进行查询
|
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1 where name='body' for update;
+----+------+
| id | name |
+----+------+
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
+----+------+
4 rows in set (0.00 sec)
|
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1 where name='body1' for update;
+----+-------+
| id | name |
+----+-------+
| 10 | body1 |
| 11 | body1 |
| 12 | body1 |
| 13 | body1 |
+----+-------+
4 rows in set (0.00 sec)
|
都可读,
好了,到这里什么问题都没有,是吧,可是接下来问题就来了,大家请看:回到第一个 session ,运行:
|
|
mysql> update test1 set name = 'bodyaaaa' where name='body';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4 Changed: 4 Warnings: 0
|
|
可以运行,那这样不是应该是正确的吗?不就是应该这样吗?好,接下来我们改变一下数据
|
|
mysql> select * from test1;
+----+-------+
| id | name |
+----+-------+
| 1 | body |
| 2 | body |
| 3 | body |
| 4 | body |
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
| 9 | body1 |
| 10 | body1 |
| 11 | body1 |
| 12 | body1 |
| 13 | body1 |
| 18 | body1 |
| 19 | body1 |
+----+-------+
15 rows in set (0.00 sec)
|
|
更改数据内容如session_1所示
|
同时查询两个session中的数据
|
mysql> begin;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from test1 where name='body' for update;
+----+------+
| id | name |
+----+------+
| 1 | body |
| 2 | body |
| 3 | body |
| 4 | body |
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
+----+------+
8 rows in set (0.00 sec)
|
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1 where name = 'body1' for update;
+----+-------+
| id | name |
+----+-------+
| 9 | body1 |
| 10 | body1 |
| 11 | body1 |
| 12 | body1 |
| 13 | body1 |
| 18 | body1 |
| 19 | body1 |
+----+-------+
7 rows in set (0.00 sec)
|
现在看不出来什么问题,感觉是正常的。
|
再去更新数据
|
mysql> select * from test1 where name='body' for update;
+----+------+
| id | name |
+----+------+
| 1 | body |
| 2 | body |
| 3 | body |
| 4 | body |
| 5 | body |
| 6 | body |
| 7 | body |
| 8 | body |
+----+------+
8 rows in set (0.00 sec)
mysql> update test1 set name='bodyaaa' where name='body';
执行等待中。。。。。
|
|
看,问题出现了,这跟上面的操作不应该是一样的吗?为什么这一次不能执行成功了呢?
|