DBMS 并发控制:时间戳和基于锁的协议
什么是并发控制?
并发控制 数据库管理系统中的事务处理是一种管理同时进行且不相互冲突的操作的过程。它确保数据库事务同时且准确地执行,以产生正确的结果,而不会违反相应数据库的数据完整性。
如果所有用户都只是读取数据,那么并发访问就相当容易。他们不可能互相干扰。但对于任何实际的数据库来说,它都会混合读取和写入操作,因此并发性是一个挑战。
DBMS 并发控制用于解决此类冲突,这些冲突大多发生在多用户系统中。因此,并发控制是数据库管理系统正常运行的最重要元素,因为数据库管理系统同时执行两个或多个数据库事务,这些事务需要访问相同的数据。
并发的潜在问题
以下是使用 DBMS 并发控制方法时可能会遇到的一些问题:
- 丢失更新 当多个事务选择同一行并根据所选值更新该行时发生
- 当第二个事务选择由另一个事务更新的行时,就会发生未提交的依赖关系问题(脏读)
- 不可重复读 当第二个事务尝试多次访问同一行并且每次读取不同的数据时,就会发生这种情况。
- 摘要错误问题 当一个事务对重复数据项的所有实例的值进行汇总,而第二个事务更新该特定数据项的几个实例时,就会发生这种情况。在这种情况下,生成的汇总不会反映正确的结果。
为什么要使用并发方法?
DBMS使用并发控制方法的原因是:
- 通过冲突事务之间的相互排斥来实现隔离
- 解决读写和写入冲突问题
- 通过不断保留执行障碍来保持数据库一致性
- 系统需要控制并发事务之间的交互。这种控制是使用并发控制方案实现的。
- 并发控制有助于确保可序列化
例如:
假设两个人同时去电子售货亭购买同一部电影、同一场次的电影票。
但是,该影院的电影座位只剩下一个。如果 DBMS 中没有并发控制,那么两个电影观众最终都可能会购买一张票。但是,并发控制方法不允许这种情况发生。两个电影观众仍然可以访问写入电影座位数据库中的信息。但并发控制只会向先完成交易过程的买家提供一张票。
并发控制协议
不同的并发控制协议在它们允许的并发量和它们施加的开销量之间提供不同的好处。以下是 DBMS 中的并发控制技术:
- 基于锁的协议
- 二相锁定协议
- 基于时间戳的协议
- 基于验证的协议
基于锁的协议
基于锁的协议 DBMS 中的一种机制是,事务在获得适当的锁之前无法读取或写入数据。基于锁的协议通过将特定事务锁定或隔离给单个用户,有助于消除 DBMS 中同时发生的事务的并发问题。
锁是与数据项关联的数据变量。此锁表示可以对数据项执行的操作。DBMS 中的锁有助于通过并发事务同步对数据库项的访问。
所有锁定请求均由并发控制管理器发出。只有锁定请求获得批准后,事务才能继续进行。
二进制锁: 数据项上的二进制锁可以处于锁定或解锁状态。
共享/独占: 这种锁定机制根据用途将 DBMS 中的锁分开。如果获取某个数据项上的锁来执行写操作,则称为排他锁。
1、共享锁(S):
共享锁也称为只读锁。使用共享锁,数据项可以在事务之间共享。这是因为您永远无权更新数据项上的数据。
例如,考虑这样一种情况,其中两个交易正在读取某人的账户余额。 数据库 将通过放置共享锁来允许他们读取。但是,如果另一个事务想要更新该帐户的余额,共享锁会阻止它,直到读取过程结束。
2.排他锁(X):
使用排他锁,可以读取和写入数据项。这是排他性的,不能同时在同一数据项上持有。使用 lock-x 指令请求 X 锁。事务可以在完成“写入”操作后解锁数据项。
例如,当一个事务需要更新某人的账户余额时。您可以通过在该事务上放置 X 锁来允许该事务。因此,当第二个事务想要读取或写入时,排他锁会阻止此操作。
3. 简单的锁协议
这种基于锁的协议允许事务在开始操作之前获得每个对象的锁。事务可以在完成“写入”操作后解锁数据项。
4. 预先申领锁定
预先声明锁协议有助于评估操作并创建启动执行过程所需的数据项列表。在授予所有锁的情况下,事务执行。之后,当所有操作结束时,所有锁都会释放。
饥饿
饥饿是指事务需要等待一段不确定的时间才能获得锁的情况。
以下是饥饿的原因:
- 当锁定物品的等待方案未得到妥善管理时
- 发生资源泄漏时
- 同一笔交易被重复选为受害者
僵局
死锁是指两个或多个进程互相等待对方释放资源,或两个以上的进程以循环链的方式等待资源的特定情况。
二相锁定协议
二相锁定协议 也称为 2PL 协议,是 DBMS 中的一种并发控制方法,通过对事务数据应用锁定来确保可序列化,从而阻止其他事务同时访问同一数据。两相锁定协议有助于消除 DBMS 中的并发问题。
该锁定协议将交易的执行阶段分为三个不同的部分。
- 在第一阶段,当事务开始执行时,它需要获得所需锁的许可。
- 第二阶段是事务获取所有锁。当事务释放其第一个锁时,第三阶段开始。
- 在此第三阶段中,事务不能请求任何新锁。相反,它仅释放已获取的锁。
两阶段锁定协议允许每个事务分两步发出锁定或解锁请求:
- 成长阶段:在此阶段事务可以获得锁,但不能释放任何锁。
- 收缩阶段:在此阶段,事务可以释放锁,但不能获取任何新锁
2PL 协议确实提供了可串行化功能。但是,它不能确保不会发生死锁。
在上图中,您可以看到本地和全局死锁检测器正在搜索死锁并通过将事务恢复到其初始状态来解决它们。
严格两阶段锁定方法
Strict-Two 锁定系统与 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 协议,要求事务在释放其中一个锁后应获取锁。它有两个阶段:增长和收缩。
- 基于时间戳的算法使用时间戳来序列化并发事务的执行。该协议使用 系统时间或逻辑计数为 时间戳。