美文网首页
事务/forupdate会锁表吗

事务/forupdate会锁表吗

作者: sizuoyi00 | 来源:发表于2020-06-29 20:59 被阅读0次

先说结论

如果条件中确定使用了索引,则会锁该行,如没有索引或没使用到索引,则会锁表。
是否使用到索引,利用trace工具判断,这里不做叙述。
建议用主键做索引验证

事务验证

1.表结构

CREATE TABLE goods (
id int(11) NOT NULL,
goods_id varchar(45) DEFAULT NULL,
goods_name varchar(45) DEFAULT NULL,
goods_num varchar(45) DEFAULT NULL,
remark varchar(45) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY goods_id_UNIQUE (goods_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

2.使用索引字段验证行锁

先打开两个连接session

1.session1开启事务并修改数据

#session1开启事务
begin;
#执行后不要提交
UPDATE goods.goods SET goods_num = '100' WHERE (goods_id = '1');
#去session2修改该条数据

注:session1此时未提交

2.session2操作,三种场景

a.session2修改该数据

UPDATE goods.goods SET goods_num = '100' WHERE (goods_id = '1');

session2修改当前数据被阻塞,因为修改属于特殊读这里会使用当前读,修改阻塞说明session1事务加了锁。但此时不能判断是行锁还是表锁。

将session1提交后,session2随即成功提交,这里阻塞了20s左右

b.session2修改其他数据

UPDATE goods.goods SET goods_num = '200' WHERE (goods_id = '2');

session2修改其他数据正常执行,说明锁的是行锁,不是表锁。

c.session2查询该数据

SELECT * FROM goods.goods where goods_id = 1;

session2查询操作正常,因为普通读时由于mysql的mvcc机制会使用的是快照度,所以不会阻塞。
mvcc当前读与快照读及其相关原理这里不做叙述

3.使用非索引字段

1.session1开启事务并修改数据

#session1开启事务
begin;
#执行后不要提交UPDATE goods.goods SET goods_num = '100' WHERE (goods_name = '1');
#去session2修改该条数据

注:session1此时未提交

2.session2操作,三种场景

a.session2修改该数据

UPDATE goods.goods SET goods_num = '100' WHERE (goods_name = '1');

session2修改当前数据被阻塞,因为修改属于特殊读这里会使用当前读,修改阻塞说明session1事务加了锁。但此时不能判断是行锁还是表锁。

将session1提交后,session2随即成功提交,这里阻塞了20s左右

b.session2修改其他数据

UPDATE goods.goods SET goods_num = '100' WHERE (goods_name = '2');

session2修改其他数据被阻塞,说明锁的是表锁,不是行锁。

将session1提交后,session2随即成功提交,这里阻塞了20s左右

c.session2查询该数据

SELECT * FROM goods.goods where goods_name = '1';

session2查询操作正常,因为普通读时由于mysql的mvcc机制会使用的是快照度,所以不会阻塞。
mvcc当前读与快照读及其相关原理这里不做叙述

加锁for update验证

注:for update只有在begin commit,也就是事务之间才会起作用,如果发现两个session都成功对一条数据加锁成功,注意看下是否有没有开启事务。

1.表结构

CREATE TABLE goods (
id int(11) NOT NULL,
goods_id varchar(45) DEFAULT NULL,
goods_name varchar(45) DEFAULT NULL,
goods_num varchar(45) DEFAULT NULL,
remark varchar(45) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY goods_id_UNIQUE (goods_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

2.使用索引字段验证行锁

先打开两个连接session

1.session1开启事务后查询加锁

#session1开启事务
begin;
#执行后不要提交
SELECT * FROM goods.goods where id = 1 for update;

注:session1此时未提交

2.session2操作,四种场景

a.session2开启事务后查询当前数据加锁

begin;
SELECT * FROM goods.goods where id = 1 for update;

由于session1加了锁,session2查询加锁被阻塞,但此时不能判断是行锁还是表锁。

将session1提交后,session2随即成功加锁,这里阻塞了20s左右

b.session2开启事务后查询其他数据加锁

begin;
SELECT * FROM goods.goods where id = 2 for update;

session2加锁其他数据正常执行,说明锁的是行锁,不是表锁。

c.session2开启事务后修改该数据

SELECT * FROM goods.goods where goods_id = 1;

session2修改当前数据被阻塞

d.session2开启事务后修改其他数据

UPDATE goods.goods SET goods_num = '100' WHERE (id = '2');

session2修改其他数据正常执行

3.使用非索引字段

1.session1开启事务并修改数据

#session1开启事务
begin;
SELECT * FROM goods.goods where goods_name = 1 for update;

注:session1此时未提交

2.session2操作,四种场景

a.session2开启事务后查询当前数据加锁

SELECT * FROM goods.goods where id = 1 for update;

由于session1加了锁,session2查询加锁被阻塞,但此时不能判断是行锁还是表锁。

将session1提交后,session2随即加锁成功,这里阻塞了20s左右

b.session2开启事务后查询其他数据加锁

SELECT * FROM goods.goods where id = 2 for update;

session2加锁其他数据也被阻塞,说明锁的是表锁,不是行锁。

将session1提交后,session2随即加锁成功,这里阻塞了20s左右

c.session2开启事务后修改该数据

UPDATE goods.goods SET goods_num = '100' WHERE (id = '1');

session2修改当前数据被阻塞,但此时不能判断是行锁还是表锁。

将session1提交后,session2随即修改成功,这里阻塞了20s左右

d.session2开启事务后修改其他数据

session2修改其他数据同样被阻塞,说明锁的是表锁,不是行锁。

将session1提交后,session2随即修改成功,这里阻塞了20s左右

相关文章

  • 事务/forupdate会锁表吗

    先说结论 如果条件中确定使用了索引,则会锁该行,如没有索引或没使用到索引,则会锁表。是否使用到索引,利用trace...

  • MySQL MyISAM和Innodb存储引擎的区别

    (1)InnoDB支持事务,MyISAM不支持事务。 (2)InnoDB支持行锁也支持表锁,MyISAM支持表锁。...

  • Oracle vs PostgreSQL,研发注意事项(1)-查

    Oracle数据库,查询语句不会锁表,但PostgreSQL在开启事务后,查询数据表会锁表,在试图DROP/TRU...

  • mysql 存储引擎之间的区别

    myisam 不支持事务 不支持外键,表锁写请求,会直接锁主整张表,myisam会认为写比读更重要, 统一采用非聚...

  • Mysql InnoDB行锁及表锁分享

    一. 背景知识 [事务(Transaction)、隔离级别、传播机制] 二. 步入正题:表锁和行锁 1.1. 表锁...

  • face_mysql

    Mysql有什么数据引擎 InnoDB,支持行级锁、表级锁、事务、索引、独立表空间,其他引擎均不支持事务Myisa...

  • 高性能Mysql笔记

    一、Mysql架构与历史 1、架构图 2、锁 表锁 行级锁 3、事务 死锁 Mysql中的事务 1

  • 两端锁协议

    1、数据库锁 数据库锁粒度划分:行锁、页锁、表锁。共享锁:读锁、S锁。事务T可以对A进行读取,其他事务只能读取而不...

  • 4:Mysql的事务隔离级别和锁机制原理

    1:概述 2:事务及其ACID属性(概述) 3:锁详解 4:会话与事务的关系 5: 表锁 6: 行锁 7:小总结

  • mysql引擎

    ISAMMYISAM=ISAM+索引+表级锁INODB= +事务+外键BERKLYDB=+事务+外键

网友评论

      本文标题:事务/forupdate会锁表吗

      本文链接:https://www.haomeiwen.com/subject/leiafktx.html