锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源,锁机制是保证数据一致性和并发性的重要手段,它的地位非常重要。
全局锁:锁定数据库中的所有表。
表级锁:每次操作锁住整张表。
行级锁:每次操作锁住对应的行数据。
共享锁(Shared Locks):也叫读锁(S锁),多个事务可以同时获取共享锁,用于读取数据,不阻塞其他事务的共享锁。
排他锁(Exclusive Locks):也叫写锁(X锁),只有一个事务可以获取排他锁,用于修改数据,其他事务无法获取共享锁或排他锁。
记录锁(Record Locks):用于保护数据表中的单个记录,当事务对记录进行修改时会自动获取记录锁。
间隙锁(Gap Locks):用于保护数据表中的间隙,即两个记录之间的空隙。间隙锁可以防止其他事务在该间隙中插入新记录。
临键锁(Next-Key Locks):是记录锁和间隙锁的组合,用于保护数据表中的记录和间隙。它可以防止其他事务在记录和间隙之间插入新记录。
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语句,已经更新操作的事务提交语句都将被阻塞。
语法
-- 加锁
flush tables with read lock ;
-- 释放锁
unlock tables ;
作用和特点
1. 锁定数据库中的所有表:全局锁会锁定整个数据库,阻止其他事务对数据库中的任何表进行修改操作。
2. 阻塞其他事务:获取全局锁的事务会阻塞其他事务对数据库的写操作,确保数据的一致性。
3. 适用于短期维护操作:全局锁通常用于执行短期维护操作,例如备份数据库、导出数据等。
实际应用场景
1. 数据库备份和恢复:在进行数据库备份和恢复操作时,为了避免备份数据的不一致性,可以使用全局锁来锁定整个数据库。
2. 数据库迁移和同步:当需要将数据库迁移到其他服务器或进行数据同步操作时,全局锁可以确保数据在迁移或同步期间不会被修改。
3. 数据库维护和优化:某些数据库维护和优化操作需要对整个数据库进行操作,此时全局锁可以保证操作的有效性和数据的完整性。
特点:
1. 锁定整张表:表级锁是在表级别上进行锁定,即一次锁定整个表,阻塞其他事务对该表的写操作。
2. 阻塞其他事务:获取表级锁的事务会阻塞其他事务对同一表的写操作,确保数据的一致性。
3. 简单高效:相对于行级锁,表级锁的实现较为简单,锁的开销较小。
1. 表锁(Table Lock):
- 表锁是一种锁定整个数据表的机制,将锁应用于整张表,阻塞其他事务对该表的写操作。
- 当一个事务获取了对表的表级锁时,其他事务无法对该表进行写操作,但可以进行读操作。
- 表锁适用于对整个表进行维护操作或需要保护整个表的情况,但会对并发性能产生影响,不适用在高并发环境中。
2. 元数据锁(Metadata Lock):
- 元数据锁用于保护数据库中的元数据,如表结构、索引等。
- 当一个事务对某个元数据对象进行修改时,会获取对应的元数据锁,阻塞其他事务对同一元数据对象的访问和修改。
- 元数据锁确保了元数据的一致性和完整性,防止并发操作导致元数据的冲突或损坏。
3. 意向锁(Intention Lock):
- 意向锁是用于协调行级锁和表级锁的机制。
- 当一个事务在某一行上持有行级锁时,意向锁会阻止其他事务获取该表的表级锁,以避免冲突。
- 意向锁分为意向共享锁(Intention Shared Lock)和意向排他锁(Intention Exclusive Lock),用于指示事务在行级别上是否持有共享锁或排他锁。
表锁有两种:表共享读锁(读锁)和 表独占写锁(写锁)
读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写
简单语法:lock tables 表名... read/write。
-- 获取表锁
lock tables 表名 write;
-- 执行需要锁定表的操作
update 表名 set column1 = 'value' where id = 1;
-- 释放表锁
unlock tables;
行级锁,每次操作锁住对应的行数据,锁定粒度最小,发生锁冲突的概率最低,并发度最高,应用在InnoDB存储引擎中。
特点
1. 锁定特定行数据:行级锁是在行级别上进行锁定,即只锁定表中的某一行数据,而不是整个表。 2. 并发性高:相比于表级锁,行级锁可以提供更高的并发性能,允许多个事务同时访问表的不同行数据。
3. 粒度细:行级锁提供了更细粒度的锁定方式,可以避免不必要的锁竞争,提高并发操作效率
行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行update和delete。在RC、RR隔离级别下都支持。
间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR隔离级别下都支持。
临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
InnoDB实现了以下两种类型的行锁:
共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他
锁。
操作的加锁机制
语法(行级锁需要在事务中使用):
-- 获取读锁、写锁
select ... lock in share mode;
select ... for update;
-- 释放锁(MySQL默认开启事务)
commit;//提交事务
rollback;//或者回滚
简单例子
-- 开启事务
start transaction;
-- 获取行级锁
select * from orders where id = 1 for update;
-- select * from orders where order_id = 1 lock in share mode;
-- 执行需要锁定行的操作
update orders set price= 100 where id = 1;
-- 提交事务,释放行级锁
commit;