数据库中的 锁机制 是用于管理并发访问的重要工具,确保多个事务同时操作数据时,数据的一致性和完整性得以维护。锁机制通过限制对数据的访问,防止并发事务之间的冲突。
1.锁的基本概念
锁(Lock) 是一种机制,用于控制对数据库资源的访问。当一个事务对某个资源(如一行数据、一张表)加锁后,其他事务必须等待锁释放才能访问该资源。
2. 锁的分类
(1)按锁的粒度(锁定范围)
-
行级锁(Row-Level Lock):
-
锁定单行数据,粒度最小,并发性最高。
-
适用于高并发场景,如 OLTP(在线事务处理)系统。
-
-
页级锁(Page-Level Lock):
-
锁定一页数据(通常是多个行的集合)。
-
粒度介于行级锁和表级锁之间。
-
-
表级锁(Table-Level Lock):
-
锁定整张表,粒度最大,并发性最低。
-
适用于低并发场景,如批量操作。
-
-
数据库级锁(Database-Level Lock):
-
锁定整个数据库,通常用于数据库维护操作。
-
(2)按锁的模式(锁定类型)
-
共享锁(Shared Lock, S Lock):
-
也称为读锁,允许多个事务同时读取同一资源。
-
共享锁之间是兼容的,但共享锁与排他锁不兼容。
-
示例:
SELECT ... LOCK IN SHARE MODE
。
-
-
排他锁(Exclusive Lock, X Lock):
-
也称为写锁,只允许一个事务独占资源。
-
排他锁与其他任何锁(包括共享锁和排他锁)都不兼容。
-
示例:
SELECT ... FOR UPDATE
。
-
-
意向锁(Intent Lock):
-
用于表明事务打算在更细粒度上加锁。
-
包括意向共享锁(IS)和意向排他锁(IX)。
-
示例:事务在表级别加意向锁,表示将在行级别加锁。
-
(3)按锁的持续时间
-
短期锁(Short-Term Lock):
-
锁的持有时间较短,通常在操作完成后立即释放。
-
示例:行级锁。
-
-
长期锁(Long-Term Lock):
-
锁的持有时间较长,可能持续整个事务。
-
示例:表级锁。
-
3. 锁的兼容性
锁的兼容性决定了多个事务能否同时持有同一资源的锁。以下是共享锁和排他锁的兼容性:
共享锁(S) | 排他锁(X) | |
---|---|---|
共享锁(S) | 兼容 | 不兼容 |
排他锁(X) | 不兼容 | 不兼容 |
-
共享锁之间可以共存。
-
排他锁与其他任何锁都不兼容。
4. 锁的实现方式
(1)悲观锁(Pessimistic Locking)
-
假设并发冲突会发生,因此在访问数据时直接加锁。
-
适用于写操作较多的场景。
-
示例:
SELECT ... FOR UPDATE
。
(2)乐观锁(Optimistic Locking)
-
假设并发冲突较少,只在提交时检查数据是否被修改。
-
通过版本号或时间戳实现。
-
适用于读操作较多的场景。
5. 死锁(Deadlock)
死锁 是指两个或多个事务相互等待对方释放锁,导致所有事务都无法继续执行。数据库系统通常通过以下方式解决死锁:
-
死锁检测:定期检查事务等待图,发现死锁后回滚其中一个事务。
-
超时机制:设置事务等待锁的超时时间,超时后回滚事务。
-
预防机制:通过锁的顺序或优先级避免死锁。