一篇文章带你了解清楚Mysql 锁
什么是锁
在多线程并发操作一个资源时,为了保证操作的正确性,需要对资源进行加锁控制。锁是用来保证共享数据或共享资源在多线程或多进程中能够安全访问的一种机制。在 MySQL 中,锁是在查询过程中对数据进行加锁以保证数据的一致性。
锁的分类
MySQL 中锁的分类有多种,这里简单介绍一下 InnoDB 中的三种锁:共享锁、排他锁和意向锁。
共享锁(Shared Lock)
共享锁可被多个线程同时持有,用来保证读的一致性。这意味着如果一个线程持有了一个共享锁,在该锁被释放之前,其他线程只能再获取到共享锁,而不能获取排他锁。其他线程因为需要对锁的改变产生的冲突而无法获取到排他锁。
示例:
session1> start transaction;
session1> select * from table_name where id=1 lock in share mode;
session2> start transaction;
session2> select * from table_name where id=1 lock in share mode; # 这条命令能执行成功
session3> start transaction;
session3> update table_name set name='new_name' where id=1; # 由于 session1 已经获取了行级共享锁,所以这条命令会一直等待,直到 session1 结束事务
排他锁(Exclusive Lock)
排他锁被获取后,其他请求的共享锁与排他锁都无法被获取,直到排他锁被释放。用来实现对数据的修改操作,在该锁被获取到之前,其他线程无法操作该行。
示例:
session1> start transaction;
session1> select * from table_name where id=1 for update;
session2> start transaction;
session2> select * from table_name where id=1 for update; # 这条命令无法执行成功,一直等待 session1 结束事务
session3> start transaction;
session3> update table_name set name='new_name' where id=1; # 由于 session1 已经获取了行级排他锁,所以这条命令会一直等待,直到 session1 结束事务
意向锁(Intent Lock)
InnoDB 存储引擎中的锁具有层级关系,需要使用意向锁和间隙锁来管理多个锁之间的关系。意向锁是一种表级锁,它表示一个事务占用了一个表中某个记录的行级别锁或者间隙锁。意向锁分为意向共享锁和意向排他锁,分别代表需要获取共享锁或排他锁。在事务需要获取行级锁之前,必须先获取表级别的意向锁。
示例:
session1> start transaction;
session1> select * from table_name where id=1 for update;
session2> start transaction;
session2> lock table table_name write;
session2> unlock tables;
session3> start transaction;
session3> insert into table_name (id, age, name) values (2,20,'lucy'); # 这条命令由于需要获取行级排他锁,但是由于 session1 已经获取了行级排他锁,所以会一直阻塞,直到 session1 结束事务
总结
游走于事务与隔离级别之间的锁机制更是整个 RDBMS 数据库系统中最核心的设计之一。正确使用锁机制可以大大提升数据系统的并发能力,提高数据的安全性。
更加深入的了解锁,可以参考 MySQL 官方文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一篇文章带你了解清楚Mysql 锁 - Python技术站