img.png

高级数据库

Database System Concepts
Seventh Edition


17章: 交易

概述:

交易的概念

Transaction Concept

交易是程序执行的一个单元, 它访问并且可能更新各种数据项.

为了保证数据的完整性, 数据库系统必须确保:

交易状态

Transaction State

交易状态图

并发执行

Concurrent Executions

系统中允许多个事务同时运行.
优点在于:

并发控制方案(实现隔离的机制)

调度: 一系列指令,指定了并发事务的指令以何种时间顺序执行.

如果一个事务成功完成其执行,它将有一个提交指令作为最后一条语句。

如果一个事务未能成功完成其执行,它将有一个中止指令作为最后一条语句。

可串行化

Serializability

基本假设: 每笔交易都保持数据库的一致性

一组事务的串行执行保持了数据库的一致性

如果一个(可能是并发的)调度等同于一个串行调度, 那么它就是可串行化的.
调度的不同等值形式引发了以下概念:

冲突可串行化

两个操作被认为是冲突的三个条件:

如果通过一系列非冲突指令的交换操作, 一个调度S能够被转换为一个调度s', 我们就说S和S'是冲突等价的.

如果一个调度S与一个串行调度在冲突方面等价, 那么就说该调度是"冲突可串行化"的.

通过一系列非冲突指令的交换, 调度表3可以转换为调度表6, 即一个连续的调度表, 其中T2遵循T1.
因此, 调度表3是"冲突可串行化"的.

冲突可串行化

不可"冲突可串行化"的调度示例:

不可冲突可串行化示例

视图可串行化

视图等价:
如果两个调度在对每个数据项的读写操作上是一致的,那么它们就是视图等价
的。这意味着,尽管两个调度可能在事务的执行顺序上有所不同,但它们对于数据库中每个数据项的最终状态的影响是相同的.

如果一个调度S与某个串行调度是视图等价的, 那么这个调度S就是视图可串行化的.

每一个冲突可串行化的调度也是视图可串行化的.

以下是一个可视图串行化但不可冲突可串行化的示例:

可视图串行化但不可冲突可串行化的示例

可串行化的测试

先行图的构建步骤:

先行图与可串行化:

可恢复性

Recoverability

需要处理事务失败对并发运行的事物的影响.

可恢复调度: 如果一个事务Tj读取了一个数据项, 该数据此前是由Ti写入的, 那么Ti的提交操作会出现在Tj的提交操作之前.

以下调度属于无法恢复

无法恢复的调度

如果T8应该终止, T9可能会读取到不一致的数据库状态. 因此, 数据库必须确保调度是可恢复的

级联回滚: 单个事务故障会导致一系列事务回滚.
以下调度中所有事物都尚未提交(因此该调度是可恢复的)

可恢复调度

缺点是可能导致大量工作的付诸东流

隔离的实施

Implementation of Isolation

隔离级别的实现:

SQL中的事物定义

Transaction Definition in SQL

在SQL中, 事务是隐式开始的.

在SQL中, 一条事务以以下方式结束:

在几乎所有数据库系统中, 默认情况下, 如果每条SQL语句执行成功, 也会隐式提交.


18章 并发控制

概述:

基于锁的协议

Lock-Based Protocols

锁是一种控制对数据项的并发访问的机制

数据项可以以两种模式锁定:

向并发控制管理器发出锁定请求. 只有在请求获得批准后, 事务才能继续进行.

锁-兼容性矩阵:

锁-兼容性矩阵

死锁

死锁

T3和T4都无法取得进展.
T4执行到 lock-S(B) 会导致T4等待T3释放对B的锁, 而T3执行到 lock-X(A) 会导致T3等待T4释放对A的锁.

这种情况称为死锁

在大多数锁定协议中存在死锁的可能性. 死锁是一种不可避免的恶果.

如果并发控制管理器设计不当, 也可能导致"饥饿".
例如:

可以设计并发控制管理器来防止饥饿现象.

续...


基于时间戳的协议

Timestamp-Based Protocols

每笔交易在进入系统时都会被赋予一个时间戳TS(Ti)

基于时间戳的协议管理并发执行, 使得时间戳顺序=可串行化顺序

几种基于时间戳的替代协议:

时间戳排序协议

Timestamp-Ordering(TSO) Protocol

为每个数据Q维护两个时间戳值:

对任何写操作施加规则以确保

假设事务Ti发出一个 read(Q)

  1. 如果 TS(Ti) ≤ W-timestamp(Q), 那么Ti需要读取一个已经被覆盖的Q的值. 因此, 读取操作被拒绝, 并且Ti被回滚
  2. 如果 TS(Ti) ≥ W-timestamp(Q), 则执行 read 操作, 并将 R-timestamp(Q) 设置为 max(R-timestamp(Q),TS(Ti))

假设事务Ti发出一个 write(Q)

  1. 如果 TS(Ti) < R-timestamp(Q), 那么Ti所生成的Q的值之前是需要的, 并且系统假定该值永远不会被生成.
    因此写入操作被拒绝, 并且Ti被回滚
  2. 如果 TS(Ti) < W-timestamp(Q), 那么Ti正试图写入Q的过时值. 因此, 此 write 操作被拒绝, 并且Ti被回滚.
  3. 否则, 执行 write 操作, 并将 W-timestamp(Q) 设置为 TS(Ti).

续...

基于验证的协议

Validation-Based Protocols

idea: 我们能将提交时间用作序列化顺序吗?

也被称为"乐观并发控制", 因此事务在执行时完全期望在验证期间一切顺利.

续...

多钟粒度

Multiple Granularity

多版本方案

Multiversion Schemes

多版本方案保留数据项的旧版本以提高并发性.
有几种变体:

Key ideas:

读操作永远不必等待, 因为会立即返回一个合适的版本.

多版本时间戳排序

续...

插入和删除操作

Insert and Delete Operations

索引结构中的并发

Concurrency in Index Structures

在线索引创建:

问题: 如何在大型关系表上创建索引而不影响并发更新

Key ideas:

索引与其他数据库项不同, 因为它们唯一的作用就是有助于访问数据.

索引结构的访问频率通常非常高, 远远高于其他数据项.
像处理其他数据库项一样处理索引结构, 例如通过对索引节点进行两阶段锁定, 可能会导致并发性低下.

存在几种索引并发协议, 其中对内部节点的锁会体检释放, 而不是以两阶段的方式释放.
只要能保持索引的准确性, 对索引进行可序列化的并发访问是可以接受的.
特别是, 只要我们能最终到达正确的叶节点, 在B+树的内部节点读取的准确值就无关紧要了.

续...

❤️ 转载文章请注明出处,谢谢!❤️