5.锁机制初探
1 概念和应用场景
mysql
支持多线程访问,可以同时处理多个用户提交的请求。在高并发的时候多个连接会 话在同一时间内发
起数据的操作。如:在商品表中有1个抢购的商品,foo
和bar
这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/