🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。
🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。
🏆本文已收录于PHP专栏:MySQL的100个知识点。
🎉欢迎 👍点赞✍评论⭐收藏
文章目录
- 一、前言
- 二、共享锁
- 三、排他锁
- 四、MySQL锁分类及使用示例
- 4.1 共享锁(Shared Lock)
- 4.2 排他锁(Exclusive Lock)
- 4.3 意向共享锁(Intention Shared Lock)和意向排他锁(Intention Exclusive Lock)
- 五、总结
一、前言
从锁的类别角度来讲,MySQL主要有两种类型的锁:共享锁(Shared Lock)和排他锁(Exclusive Lock)。
二、共享锁
共享锁是用于读取操作的,并且可以被多个会话同时持有。共享锁不会阻塞其他会话持有共享锁,但会阻塞其他会话请求排他锁。示例如下:
-- 会话1
START TRANSACTION;
SELECT * FROM table_name WHERE column_name = 'value' LOCK IN SHARE MODE;
-- 执行读取操作
-- 会话2
START TRANSACTION;
SELECT * FROM table_name WHERE column_name = 'value' LOCK IN SHARE MODE;
-- 执行读取操作
在上面的示例中,会话1和会话2都持有一个共享锁来读取表中的数据。由于共享锁可以同时被多个会话持有,所以这里不会出现阻塞的情况。
三、排他锁
排他锁是用于写入操作的,并且只能被单个会话持有。排他锁会阻塞其他会话请求排他锁和共享锁。示例如下:
-- 会话1
START TRANSACTION;
SELECT * FROM table_name WHERE column_name = 'value' FOR UPDATE;
-- 执行读取并加上排他锁
-- 会话2
START TRANSACTION;
SELECT * FROM table_name WHERE column_name = 'value' FOR UPDATE;
-- 这个查询将会被阻塞,直到会话1释放排他锁
-- 会话1
UPDATE table_name SET column_name = 'new_value' WHERE column_name = 'value';
COMMIT;
-- 释放排他锁,允许会话2继续执行
-- 会话2
SELECT * FROM table_name WHERE column_name = 'value' FOR UPDATE;
-- 执行读取并加上排他锁
在上面的示例中,会话1先获取了一个排他锁来读取数据,这导致会话2的请求被阻塞。直到会话1释放了排他锁后,会话2才能继续执行。
除了共享锁和排他锁,MySQL还有其他类型的锁,如意向共享锁(Intention Shared Lock)和意向排他锁(Intention Exclusive Lock)。这些锁是用于提高并发性能和减少死锁的。
下面是一个完整的博文:
四、MySQL锁分类及使用示例
在MySQL中,锁是用于控制并发访问的重要机制。通过合理地使用锁,可以提高系统的并发性能,保证数据的一致性。本文将介绍MySQL中的常见锁分类,并给出相应的使用示例。
4.1 共享锁(Shared Lock)
共享锁(也称为读锁)适用于读取操作,可以被多个会话同时持有。共享锁不会阻塞其他会话持有共享锁,但会阻塞其他会话请求排他锁。
示例:假设存在一个名为books
的表,我们希望在读取某本书的信息时使用共享锁。
-- 会话1
START TRANSACTION;
SELECT * FROM books WHERE book_id = 123 LOCK IN SHARE MODE;
-- 执行读取操作
-- 会话2
START TRANSACTION;
SELECT * FROM books WHERE book_id = 123 LOCK IN SHARE MODE;
-- 执行读取操作
在上述示例中,会话1和会话2都持有一个共享锁来读取books
表中特定书籍的信息。由于共享锁可以同时被多个会话持有,因此不会出现阻塞的情况。
4.2 排他锁(Exclusive Lock)
排他锁(也称为写锁)适用于写入操作,只能被单个会话持有。排他锁会阻塞其他会话请求排他锁和共享锁。
示例:假设存在一个名为books
的表,我们希望在更新某本书的信息时使用排他锁。
-- 会话1
START TRANSACTION;
SELECT * FROM books WHERE book_id = 123 FOR UPDATE;
-- 执行读取并加上排他锁
-- 会话2
START TRANSACTION;
SELECT * FROM books WHERE book_id = 123 FOR UPDATE;
-- 这个查询将会被阻塞,直到会话1释放排他锁
-- 会话1
UPDATE books SET price = 10.99 WHERE book_id = 123;
COMMIT;
-- 释放排他锁,允许会话2继续执行
-- 会话2
SELECT * FROM books WHERE book_id = 123 FOR UPDATE;
-- 执行读取并加上排他锁
在上述示例中,会话1首先获取了一个排他锁来读取书籍的信息,这导致会话2的请求被阻塞。直到会话1释放了该排他锁后,会话2才能继续执行。
4.3 意向共享锁(Intention Shared Lock)和意向排他锁(Intention Exclusive Lock)
意向共享锁和意向排他锁是MySQL中的辅助锁机制,用于提高并发性能和减少死锁的可能性。这两种锁不需要用户主动设置,由数据库系统自动管理。
- 意向共享锁(IS):表示一个事务对数据行有意向地加共享锁。
- 意向排他锁(IX):表示一个事务对数据行有意向地加排他锁。
示例:假设存在一个名为products
的表,我们希望在使用排他锁更新某个产品的销售数量之前,先使用意向共享锁来检查该产品的库存。
-- 会话1
START TRANSACTION;
SELECT * FROM products WHERE product_id = 456 LOCK IN SHARE MODE;
-- 执行读取操作,并加上意向共享锁
-- 会话2
START TRANSACTION;
SELECT * FROM products WHERE product_id = 456 LOCK IN SHARE MODE;
-- 执行读取操作,并加上意向共享锁
-- 会话1
SELECT * FROM products WHERE product_id = 456 FOR UPDATE;
-- 执行读取并加上排他锁
-- 会话2
SELECT * FROM products WHERE product_id = 456 FOR UPDATE;
-- 这个查询将会被阻塞,直到会话1释放排他锁
在上述示例中,会话1和会话2都先获取了一个意向共享锁来读取产品的信息,在使用排他锁更新销售数量之前先进行了检查。这样的设计可以降低死锁的可能性,并提高并发性能。
除了以上介绍的常用锁,MySQL还提供其他类型的锁,如记录锁(Record Lock)和间隙锁(Gap Lock)。这些锁用于更细粒度的并发控制,但需要根据具体的场景来决定是否使用。
五、总结
在MySQL中,根据锁的类别可以将锁分为共享锁和排他锁。共享锁适用于读取操作,可被多个会话同时持有;排他锁适用于写入操作,只能被单个会话持有。通过合理地使用这些锁,可以实现对数据的并发访问控制,并提高系统的性能与稳定性。
本文介绍了MySQL中的锁分类,并给出了具体的使用示例。当我们在开发或维护MySQL数据库时,应根据实际需求选择合适的锁来保证数据的一致性和并发性能。同时,还需注意避免死锁的产生,使用锁的过程中应注意事务的隔离级别等相关配置,以充分发挥锁机制的作用。