Skip to main content

5.锁机制初探

1 概念和应用场景


mysql支持多线程访问,可以同时处理多个用户提交的请求。在高并发的时候多个连接会 话在同一时间内发 起数据的操作。如:在商品表中有1个抢购的商品,foobar这2个用 户在同一时间内抢购,foo先抢到了 ,但在数据库还没来得及修改商品的数量修改为0的时候, bar也已经成功抢了1个,这时候出现了1个商品 却被抢了2次商品。这数据是不对的,这就是脏读,而InoDB引擎的锁机制能解决这个问题。即,当一个会话 在进行操作的时候,后面的请求在操作提交或 事务回滚前,其它后面的用户操作是不会进行操作的,直到完 成,才进行下一个,从而保证 了数据的准确。

2 生成测试数据

先来做个测试,来直观感觉下。开始前先创建个test测试数据库和demo表来演示。

create databse test;  
use test;
CREATE TABLE `test`.demo
(
`id` INT(10) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(80) NOT NULL , PRIMARY KEY (`id`)
) ENGINE = InnoDB;
--- 加入3条数据
INSERT INTO `test`.`demo` (`id`, `name`)
VALUE
(NULL, 'A'), (NULL, 'B'), (NULL, 'C');
SET AUTOCOMMIT = 0; --- 关闭自动提交,开启事务

3 A和B窗口会话

目前为止我们的所有操作都是在一个窗口(第一个)下操作的,下文称A窗口. 好,现在我们查看到的数据是这样的。

SELECT * FROM  `test`.`demo`;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+

然后对第一条数据行修改,并查看下

UPDATE `test`.`demo` SET `name` = 'I am A bebore to change' WHERE `id` = 1;
SELECT * FROM `demo`;
+----+-------------------------+
| id | name |
+----+-------------------------+
| 1 | I am A bebore to change |
| 2 | B |
| 3 | C |
+----+-------------------------+

结果很明显,数据已经发生改变了。

warning

注意啊,画重点的来了。

然后再打开一个新的窗口,下文称B窗口

use `test`;
SELECT * FROM `test`.`demo`;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
UPDATE `test`.`demo` SET `name` = 'B windows go to changing id 1' WHERE `id` = 1;

显然A窗口修改并没有生效,B窗口就这个事务的隔离后面再说。然后B窗口就一直卡在这里了。 甚至超时而执行失败。 如果这时候把回到A窗口的事务提交下.

UPDATE `test`.`demo` SET `name` = 'I am A bebore to change' WHERE `id` = 1;
SELECT * FROM `demo`;
+----+-------------------------+
| id | name |
+----+-------------------------+
| 1 | I am A bebore to change |
| 2 | B |
| 3 | C |
+----+-------------------------+
commit;

由于A窗口的事务已经不占用那条记录了,那B窗口自然可以执行下去。

其实B窗口操作的数据行和A窗口是一样。B窗口卡在这里是等A窗口执行完成后,才轮到B窗口来操作。 而B个窗口执行的更新语句也成功执行了。并修改成功了

use `test`;
SELECT * FROM `test`.`demo`;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
UPDATE `test`.`demo` SET `name` = 'B windows go to changing id 1' WHERE `id` = 1;
Query OK, 1 row affected (11.196 sec)
Rows matched: 1 Changed: 1 Warnings: 0
SELECT * FROM `test`.`demo`;

+----+-------------------------------+
| id | name |
+----+-------------------------------+
| 1 | B windows go to changing id 1 |
| 2 | B |
| 3 | C |
+----+-------------------------------+
3 rows in set (0.000 sec)

commit;

小结


锁机制保证了数据的准确性,防止数据同时操作而导致脏读的情况。

感谢后盾人提供这么好的学习视频。 https://www.houdunren.com/