mysql 表锁 MDL锁 行锁

  • mysql 按照粒度分可以分为 全局锁 表锁 行锁

全局锁

  • 给整个锁加上锁
  • Flush tables with read lock 让数据处于只读的状态 一般用户
  • 场景:做全库的逻辑备份。

表锁 顾名思义 锁住一整张表

  • 表锁 分为 读锁 写锁 以及DML(元数据)锁
  • 看读锁 (共享锁)

  • 多个事物可以共享访问该数据,不可执行ddl操作 当前加锁事物只可查询当前表
  • 事物1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> lock table user read;
Query OK, 0 rows affected (0.00 sec)

//由于没有释放锁 所以无法在去给其它表加读锁(共享锁),必须先commit 释放当前锁
mysql> select * from user_profile;
ERROR 1100 (HY000): Table 'user_profile' was not locked with LOCK TABLES

  • 事物2
 begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user;

  • 实验1 测试完毕 记得UNLOCK TABLES!!

写锁

  • 事物1
mysql> lock table user write;
Query OK, 0 rows affected (0.01 sec)



mysql> 

  • 事物2

//会一直阻塞 直到事物commit
mysql> select * from user;

  • UNLOCK TABLES!!

  • 这里可能有人问了,为什么不加begin ?,因为mysql 中每一条单独的语句都是一个事物

  • DML锁

  • 每个事物开始时都会默认加上一个DML 锁

  • 这个锁也啥用?

  • DML保证你在查询的时候表结构不会被破坏,当你开启事物在执行阶段时 你无法修改表结构,动手试试!!

行锁 ( 行锁由innodb 引擎特有)

# test表结构
id int 主键自增
age int 
name varchar(128)


  • 话不多说看代码

  • 事物1

begin;
update set name='1' where id=1;
  • 事物2

# 这个不会阻塞 我们可以直到mysql 在这里为我们加了行锁,没有锁住整张表
update set name='2' where id=2; 
  • commit 以下 在进行下面的操作

  • 实验2

  • 事物1

begin;
update set age=12 where name='wangwu';
  • 事物2
# 呜呜! 这里居然阻塞住了?为什么 
update set  age=12 where name='zhangsan'; 
  • 为啥会阻塞? 行锁消失了?
  • 因为 在innodb 中 行锁是加在索引上的,在test 表中有默认聚簇索引 id,所有当前我们使用条件where id=1 时,innodb默认为我们给id=1 这行数据加上锁,
  • 但是where name 时 ,name列上并没有索引,索引行锁失效了 innodb改用为表锁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值