全局锁
- 给整个锁加上锁
- Flush tables with read lock 让数据处于只读的状态 一般用户
- 场景:做全库的逻辑备份。
表锁 顾名思义 锁住一整张表
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
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)
begin;
update set name='1' where id=1;
# 这个不会阻塞 我们可以直到mysql 在这里为我们加了行锁,没有锁住整张表
update set name='2' where id=2;
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改用为表锁