来自事务的需要
事务作为数据库操作的执行单位,要么全部成功,要么全部失败。
往往依赖于日志以及锁。
日志
日志可以将操作、数据记录甚至是数据页的记录偏移和内容记录下来,便于事务的回滚。
比如在以下场景:多个client对于记录A和B的值进行更改,会首先被记录到日志模块里;日志模块会自己设计策略,安排将操作更新到磁盘的时机。(过于频繁会导致大量I/O开销,反之则数据滞后。)

锁
而锁保证了数据库事务在表级、记录级的下的ACID特性。我们接下来会展开说说。
锁的特点
注意,数据库的锁与我们在操作系统里用的Latch关系不大。
试想我们给成千上万个数据记录加上几百字节的互斥锁或者共享锁的开销。
数据库的锁一般有记录级、表级、表空间级,有以下的特点:
- 与OS的Latch相似,写时互斥,读时共享。
- 持有时间会相对长(等待事务结束)。
- 数量庞大(一个会话可能持有成百上千的记录锁)。
- 每个session同一个时刻只能等待一把锁。要按照先来后到的顺序获取锁。
锁的实现原则
- 在数据库的本身的数据结构中实现,表锁加在表的数据结构中;记录锁加在记录的数据结构中。
- 每个session可能会持有非常多的锁。
- 每个session锁遵循先来后到的原则。
乐观锁和悲观锁
悲观锁:认为数据易被并发修改,产生冲突。因此在修改数据前先锁定数据。典型的为读锁和写锁。
乐观锁:与悲观锁相反。修改前先不锁定数据,修改完后等到要提交更新的数据再检查是否发生冲突。如果有再回滚。
锁使用的场景
下图中,session a试图获得记录C的互斥锁;
session b也试图获得记录C的互斥锁,但根据先来后到原则,它需要通过指针链到session a后。
session c也试图获得记录C的共享锁,但根据先来后到原则,它需要通过指针链到session b后。

session a处理完后,唤醒session b获取记录C的互斥锁。

此时session d请求记录C的共享锁,根据先来后到原则,它通过指针链到session c后。

b释放锁之后,唤醒session c和session d获取记录C的共享锁。

本文探讨了数据库事务中锁的作用,强调了日志在事务回滚中的重要性。接着分析了数据库锁的特点,与操作系统中的Latch不同,数据库锁更注重长期持有和大量使用,并遵循先来后到的获取原则。同时,介绍了悲观锁和乐观锁的概念及应用场景,说明了在并发访问时如何协调不同session的锁请求。
170万+

被折叠的 条评论
为什么被折叠?



