闽公网安备 35020302035485号
想象一下,你走进了一个熙熙攘攘的舞厅,舞者们在快节奏的音乐下翩翩起舞,每个人都在寻找自己的舞伴和舞台。在数据库的世界里,这个舞厅就是我们的数据表,而舞者们则是那些并发的请求。MySQL的并发控制机制,就像是舞厅中的舞伴协调员,确保每个请求都能找到合适的舞伴,展现自己的优雅舞姿,而不会踩到别人的脚。
「MVCC」:通过保存数据的多个版本,允许读写操作并发执行,而不互相干扰。
「意向锁(Intention Lock)」:表明事务打算在表中的某些行上加锁。
BEGIN; SELECT * FROM tickets WHERE id = 100 FOR UPDATE; -- 若检查票尚未被预订,则进行预订操作 COMMIT;这里使用FOR UPDATE来加排他锁,保证了在事务完成前,其他事务无法修改这张票的信息。
「Undo Log」:当需要回滚时,用于恢复数据的旧版本。
-- 事务A
BEGIN;
SELECT COUNT(*) FROM users; -- 返回1000
-- 事务B同时插入新用户
INSERT INTO users (name) VALUES ('New User');
-- 事务A再次统计用户总数
SELECT COUNT(*) FROM users; -- 依然返回1000
COMMIT;
由于MVCC的存在,事务A两次查询的结果一致,它没有看到事务B的插入操作,从而避免了幻读的问题。-- 粉丝A抢购座位1 START TRANSACTION; SELECT * FROM concert_tickets WHERE seat_id = 1 FOR UPDATE; -- 粉丝B几乎同时抢购座位2 START TRANSACTION; SELECT * FROM concert_tickets WHERE seat_id = 2 FOR UPDATE; -- 粉丝A完成购买 UPDATE concert_tickets SET status = 'sold' WHERE seat_id = 1; COMMIT; -- 粉丝B也完成购买 UPDATE concert_tickets SET status = 'sold' WHERE seat_id = 2; COMMIT;由于每个座位是独立的行,行锁允许两个粉丝可以同时进行操作,而不会相互阻塞。
-- 管理员开始盘点,加表锁 LOCK TABLES books READ; -- 此时任何试图修改books表的操作都将会等待此锁释放 -- 例如,读者尝试借书 -- UPDATE books SET status = 'borrowed' WHERE id = 123; -- 此操作将被阻塞 -- 管理员完成盘点 UNLOCK TABLES;在管理员盘点过程中,读者的借阅操作将会被暂停,直到盘点结束,表锁被释放。
-- 活动策划者开始更新商品信息,加意向排他锁
START TRANSACTION;
INSERT INTO intention_locks (table_name, lock_type) VALUES ('products', 'IX');
-- 此时,会计团队打算对所有商品进行价格核算,需要加表共享锁
-- 但因为存在意向排他锁,会计团队的操作需要等待
-- LOCK TABLES products READ; -- 此操作将被阻塞
-- 活动策划者完成商品信息更新
COMMIT;
-- 意向锁释放后,会计团队可以加表共享锁进行核算
LOCK TABLES products READ;
通过意向锁,数据库在事务之间建立了清晰的沟通,确保了锁的兼容性和协调性。