DBMS 并发控制:时间戳和锁基协议
什么是并发控制?
数据库管理系统中的并发控制是一种在不发生冲突的情况下管理同时操作的流程。它确保数据库事务同时准确地执行,以产生正确的结果,同时不违反相应数据库的数据完整性。
如果所有用户都只是读取数据,那么并发访问就非常容易。他们之间不可能相互干扰。尽管对于任何实际的数据库来说,它都会混合读取和写入操作,因此并发是一个挑战。
DBMS 并发控制用于解决此类冲突,这些冲突主要发生在多用户系统中。因此,并发控制是数据库管理系统正常运行的最重要元素,其中两个或多个数据库事务同时执行,需要访问相同的数据。
并发的潜在问题
在使用 DBMS 并发控制方法时,您可能会遇到以下一些问题。
- 丢失更新发生在多个事务选择同一行并基于所选值更新该行时。
- 当第二个事务选择由另一个事务更新的行时(脏读),会发生未提交的依赖性问题。
- 不可重复读发生在第二个事务尝试多次访问同一行,但每次读取的数据都不同时。
- 不正确的摘要问题发生在当一个事务对重复数据项的所有实例的值进行汇总,而第二个事务更新该特定数据项的某些实例时。在这种情况下,结果摘要不反映正确结果。
为什么使用并发方法?
在 DBMS 中使用并发控制方法的原因
- 通过冲突事务之间的互斥来实现隔离。
- 解决读-写和写-写冲突问题。
- 通过持续维护执行阻塞来保持数据库一致性。
- 系统需要控制并发事务之间的交互。这种控制是通过并发控制方案实现的。
- 并发控制有助于确保可串行化。
示例
假设两个人同时去电子售票机为同一部电影和同一场次购票。
然而,在那家特定影院的这场电影中只有一个座位了。如果没有 DBMS 中的并发控制,这两人都有可能最终购买到票。然而,并发控制方法不允许这种情况发生。两人仍然可以访问电影座位数据库中写入的信息。但并发控制只向第一个完成交易过程的购买者提供一张票。
并发控制协议
不同的并发控制协议在它们允许的并发量和它们施加的开销量之间提供不同的好处。以下是 DBMS 中的并发控制技术:
- 基于锁的协议
- 两阶段锁定协议
- 基于时间戳的协议
- 基于验证的协议
基于锁的协议
DBMS 中的基于锁的协议是一种机制,在该机制中,事务在获得适当的锁之前无法读取或写入数据。基于锁的协议通过锁定或隔离单个用户的特定事务来帮助消除 DBMS 中并发事务的并发问题。
锁是与数据项关联的数据变量。此锁表示可以对数据项执行的操作。DBMS 中的锁有助于同步并发事务对数据库项的访问。
所有锁请求都发送给并发控制管理器。只有在授予锁请求后,事务才能继续。
二进制锁:数据项上的二进制锁可以处于锁定或解锁状态。
共享/独占:此类型的锁定机制根据其用途区分 DBMS 中的锁。如果为了执行写操作而获取数据项上的锁,则称为独占锁。
1. 共享锁 (S)
共享锁也称为只读锁。有了共享锁,数据项就可以在事务之间共享。这是因为您永远无权更新数据项上的数据。
例如,假设有两个事务正在读取一个人的账户余额。数据库将通过放置共享锁来允许它们读取。但是,如果另一个事务想要更新该账户的余额,共享锁会阻止它,直到读取过程结束。
2. 独占锁 (X)
使用独占锁,数据项可以被读取和写入。这是独占的,不能在同一数据项上并发持有。X 锁是使用 lock-x 指令请求的。事务可以在完成“写入”操作后解锁数据项。
例如,当一个事务需要更新一个人的账户余额时。您可以为其加上 X 锁来允许该事务。因此,当第二个事务想要读取或写入时,独占锁会阻止该操作。
3. 简洁锁协议
此类基于锁的协议允许事务在开始操作之前获取每个对象的锁。事务可以在完成“写入”操作后解锁数据项。
4. 预声明锁定
预声明锁定协议有助于评估操作并创建需要的数据项列表,以便启动执行过程。当所有锁都被授予时,事务执行。之后,当所有操作都完成后,所有锁都会释放。
饥饿
饥饿是指事务需要无限期等待才能获取锁的情况。
饥饿的原因如下:
- 当锁定的项目的等待方案未得到妥善管理时。
- 在资源泄漏的情况下。
- 同一个事务被反复选为牺牲品。
死锁
死锁是指两个或多个进程互相等待释放资源,或者两个以上的进程在一个循环链中等待资源的情况。
两阶段锁定协议
两阶段锁定协议也称为 2PL 协议,是 DBMS 中一种并发控制方法,它通过对事务数据应用锁来确保可串行化,从而阻止其他事务同时访问相同的数据。两阶段锁定协议有助于消除 DBMS 中的并发问题。
此锁定协议将事务的执行阶段分为三个不同的部分。
- 在第一阶段,当事务开始执行时,它需要获得所需锁的许可。
- 第二部分是事务获得所有锁的地方。当事务释放其第一个锁时,第三阶段开始。
- 在第三阶段,事务不能要求任何新锁。相反,它只释放已获取的锁。
两阶段锁定协议允许每个事务分两步进行锁或解锁请求:
- 增长阶段:在此阶段,事务可以获取锁,但不能释放任何锁。
- 收缩阶段:在此阶段,事务可以释放锁,但不能获取任何新锁。
2PL 协议确实提供了可串行化。但是,它不能保证不会发生死锁。
在上图所示的图中,您可以看到本地和全局死锁检测器正在搜索死锁,并通过将事务恢复到初始状态来解决它们。
严格两阶段锁定方法
严格两阶段锁定系统与 2PL 几乎相同。唯一的区别是 Strict-2PL 从不释放已使用的锁。它在提交点之前持有所有锁,并在过程完成后一次性释放所有锁。
集中式 2PL
在集中式 2 PL 中,单个站点负责锁定管理过程。它只有一个用于整个 DBMS 的锁管理器。
主副本 2PL
主副本 2PL 机制,将多个锁管理器分布到不同的站点。之后,特定锁管理器负责管理一组数据项的锁。当主副本更新后,更改会传播到从副本。
分布式 2PL
在这种两阶段锁定机制中,锁管理器分布到所有站点。它们负责管理该站点数据的锁。如果没有复制数据,则等同于主副本 2PL。分布式 2PL 的通信成本比主副本 2PL 高得多。
基于时间戳的协议
DBMS 中的基于时间戳的协议是一种算法,它使用系统时间或逻辑计数器作为时间戳来序列化并发事务的执行。基于时间戳的协议确保所有冲突的读写操作都按时间戳顺序执行。
在该方法中,总是优先处理较旧的事务。它使用系统时间来确定事务的时间戳。这是最常用的并发协议。
基于锁的协议可以帮助您管理冲突事务在执行时的顺序。基于时间戳的协议在创建操作时即可管理冲突。
示例
Suppose there are there transactions T1, T2, and T3. T1 has entered the system at time 0010 T2 has entered the system at 0020 T3 has entered the system at 0030 Priority will be given to transaction T1, then transaction T2 and lastly Transaction T3.
优点:
- 与 2PL 协议一样,调度也是可串行化的。
- 事务无需等待,从而消除了发生死锁的可能性!
缺点
如果同一个事务反复重启和中止,则可能发生饥饿。
验证基协议
DBMS 中的基于验证的协议也称为乐观并发控制技术,是一种避免事务并发的方法。在此协议中,更新的是事务数据的本地副本而不是数据本身,从而减少了事务执行时的干扰。
基于验证的协议执行三个阶段:
- 读取阶段
- 验证阶段
- 写入阶段
读取阶段
在读取阶段,事务可以读取数据库中的数据值,但写操作或更新仅应用于本地数据副本,而不是实际数据库。
验证阶段
在验证阶段,检查数据以确保在将事务更新应用于数据库时没有违反可串行化。
写入阶段
在写入阶段,如果验证成功,则将更新应用于数据库;否则,不应用更新,并且事务被回滚。
良好并发协议的特性
理想的并发控制 DBMS 机制具有以下目标:
- 必须能够抵御站点和通信故障。
- 它允许事务的并行执行以实现最大并发。
- 其存储机制和计算方法应适度,以尽量减少开销。
- 它必须对事务的原子操作结构施加一些约束。
摘要
- 并发控制是 DBMS 中用于在不发生冲突的情况下管理并发操作的流程。
- 由于缺乏并发控制而导致的问题包括丢失更新、脏读、不可重复读和不正确的摘要问题。
- 基于锁、两阶段、基于时间戳、基于验证是并发处理协议的类型。
- 锁可以是共享 (S) 或独占 (X)。
- 两阶段锁定协议,也称为 2PL 协议,要求事务在释放一个锁后获取一个锁。它有增长和收缩两个阶段。
- 基于时间戳的算法使用时间戳来序列化并发事务的执行。该协议使用系统时间或逻辑计数作为时间戳。