【mysql】锁机制初探

概念和应用场景


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

生成测试数据

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

1
2
3
4
5
6
7
8
9
10
11
12
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; --- 关闭自动提交,开启事务

A和B窗口会话

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

1
2
3
4
5
6
7
8
SELECT * FROM  `test`.`demo`;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+

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

1
2
3
4
5
6
7
8
9
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 |
+----+-------------------------+

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

注意啊,画重点的来了。


然后再打开一个新的窗口,下文称B窗口
1
2
3
4
5
6
7
8
9
10
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窗口的事务提交下.

1
2
3
4
5
6
7
8
9
10
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个窗口执行的更新语句也成功执行了。并修改成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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/

坚持原创技术分享,您的支持将鼓励我继续创作!
0%