码迷,mamicode.com
首页 > 数据库 > 详细

Mysql锁机制--行锁

时间:2018-04-24 17:46:39      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:int   arc   插入   第一步   get   注意   varchar   五步   log   

 

Mysql 系列文章主页 

 

===============

 

1 准备数据

1.1 建表

DROP TABLE IF EXISTS employee;
CREATE TABLE IF NOT EXISTS employee (
    id INT PRIMARY KEY auto_increment,
    name VARCHAR(40),
        money INT
)ENGINE INNODB;

注意:ENGINE 是 INNODB(因为 InnoDB 才支持行锁)

1.2 插入数据

INSERT INTO employee(name, money) VALUES(Alice, 10000);
INSERT INTO employee(name, money) VALUES(Bob, 10000);

2 测试

2.1 测试前准备

  • 准备两个会话(终端、命令行),一个白色的(记为:左),一个黑色的(记为:右)
  • 两个会话均设置 autocommit = 0

命令如下:

SET autocommit = 0;

在左侧会话中执行的结果:

技术分享图片

在右侧会话中执行的结果:

技术分享图片

2.2 更新不同行

2.2.1 测试

第一步:在左侧会话中执行

UPDATE employee SET money = money + 10000 WHERE id = 1;

技术分享图片

第二步:在右侧会话中执行

UPDATE employee SET money = money + 5000 WHERE id = 2;

技术分享图片

可以看到,左右两个会话可以同时分别执行,不会相互产生影响。

第三步:两个终端都提交

技术分享图片

技术分享图片

第四步:两个终端分别查询

SELECT * FROM employee; 

技术分享图片

技术分享图片

结果是,两个终端查询的结果相同,且这两条数据库记录分别是被这两个终端更新后的结果(10000+10000=20000,10000+5000=15000)。

2.2.2 结论

对于 InnoDB 默认的行锁来说,如果更新不同的行,它们可以同时操作、不会相互影响。

2.3 更新同一行

2.3.1 测试

第一步:在左侧会话中执行

UPDATE employee SET money = money + 10000 WHERE id = 1; 

技术分享图片

第二步:在右侧会话中执行

UPDATE employee SET money = money - 1000 WHERE id = 1;

技术分享图片

可以看到,Sql语句被挂起(阻塞)!

第三步:左侧执行COMMIT(注意看右侧会话中Sql语句执行的变化)

技术分享图片

第四步:注意右侧会话

技术分享图片

第五步:右侧执行COMMIT

技术分享图片

第六步:查看左侧结果

技术分享图片

第七步:查看右侧结果

技术分享图片

可以看到,左右两侧结果相同,且正确(20000+10000=30000-1000=29000)

2.3.2 结论

InnoDB 行锁,当更新同一行时,在前一个会话未提交之前,后一个会话的更新操作会被阻塞(挂起),直到前一个会话提交后,后一个更新操作才能得以执行。

3 结论

InnoDB 行锁,当更新不同行时不会相互影响,只有更新同一行时才会产生阻塞。

Mysql锁机制--行锁

标签:int   arc   插入   第一步   get   注意   varchar   五步   log   

原文地址:https://www.cnblogs.com/cyhbyw/p/8861384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!