MYSQL中的三种锁

MYSQL中的三种锁:全局锁、表锁和行锁。

全局锁就是对整个数据库加锁,加了全局锁之后,整个数据库变为只读状态。
MYSQL有两种加全局锁的方法:一是使用命令Flush tables with read lock(FTWRL),二是set global readonly=true。

两种方法的区别是:FTWRL使用了之后,全库就进入了更新阻塞的状态,此时可以对数据库进行读取和备份,不论数据库引擎是否支持事务,都可以用FTWRL来让数据库进入只读状态;比如MyISAM这种不支持事务的引擎,备份就只能通过 FTWRL。readonly也可以让全库进入只读状态,但是readonly一般会被用来做逻辑,比如用来判断一个库是主库还是备库。

表级锁就是对一张表加锁,表锁分两种:表锁和元数据锁。
表锁的命令:lock tables 表名 read/write,用 unlock tables主动释放锁。
命令格式例如:

lock tables T read;
select * from T limit 10;
unlock tables;

元数据锁是隐式加锁,也就是不需要我们去写命令行来启动,访问一个表的时候会被自动加上。元数据锁的作用是,保证读写的正确性。例如一个线程的事务正在查询表T,另一个线程的事务却要删掉其中一列,如果这两个事务并行,那结果应该是什么样的呢?MYSQL的处理就是不允许同时执行,也就是要修改表结构需要先拿到元数据锁。

行锁就是只锁一行数据,MYSQL的行锁是由各自的引擎自行实现的。InnoDB支持行锁,MyISAM引擎不支持行锁。

行锁中的两阶段锁
行锁并不是事务启动的时候就启动,而是在需要的时候才启动,并且也不是语句执行完就释放锁,而是事务结束才释放行锁,这就是两阶段锁。

行锁降低了锁的并发粒度,但是同时也存在并发造成的死锁问题,造成死锁的原因就是循环依赖,这点在平时的开发中要格外注意。