(数据库原理与应用)事务 -13

149 阅读6分钟

事务的基本概念

定义

事务是一组程序执行单元,它访问并可能更新各种数据项。例如,将钱从一个账户转移到另一个账户。

事务的目的

处理两个问题:

  1. 并发执行多个事务时,不会导致不一致的状态,这由并发控制方案来保证。
  2. 各种类型的故障,如硬件故障和系统崩溃,不会导致不一致的状态,这由恢复方案来保证。

事务的例子

从账户A转账$50到账户B的事务:

  1. 读取(A)
  2. A = A – 50
  3. 写入(A)
  4. 读取(B)
  5. B = B + 50
  6. 写入(B)

read(X):将数据项X从数据库传输到事务在内存中的工作区域中的变量(也称为X)。

write(X):将变量X的值传输到数据库中的数据项X。

ACID属性

为了保持数据的完整性,数据库系统必须确保事务的以下属性:

原子性(Atomicity)

事务的所有操作要么正确地反映在数据库中,要么没有。确保原子性是恢复系统的责任。

持久性(Durability)

事务完成后,它对数据库仍然存在,即使存在系统故障也是如此。确保持久性是恢复系统的责任

隔离性(Isolation)

来自其他并发执行事务的中间不一致状态必须被隐藏。确保隔离是并发控制系统的责任。

一致性(Consistency)

如果事务从一致的数据库开始以原子方式独立运行,则数据库在事务结束时必须再次保持一致。 确保一致性是应用程序程序员的责任。

事务的状态

image.png

Active

事务在执行时保持此状态

Partially committed

在最后的语句被执行之后的状态

Committed

成功完成后

Failed

在发现正常的执行不能继续进行之后。例如,错误的输入,没有找到数据,硬件在发现正常的执行不能继续进行之后。例如,错误的输入,没有找到数据,硬件

Aborted

事务回滚之后

部分提交和提交之间发生的情况将在稍后的基于日志的恢复中讨论

并发执行(Concurrent Executions)

使用并发执行增加了吞吐量(throughput)(给定时间内执行的事务数量)和资源利用率

一个事务可以在使用CPU的同时,另一个事务正在读取或写入磁盘。减少了平均响应时间(average response time)(提交事务后完成的平均时间)

短事务不需要在长事务之后等待

并发控制方案

实现隔离的机制;即控制并发事务之间的交互

调度(Schedules)

指定并发事务指令执行的顺序

串行调度(Serial Schedule)

事务一个接一个地执行,没有交叉

image.png

并发调度(Concurrent Schedule)

image.png

可串行化(Serializability)

如果一个调度能够与某个串行调度等价,它就是“可串行化”的,也叫“可串行化调度”

指令的执行顺序

考虑两个连续的指令 I 和 J,它们属于两个不同的事务。

  1. 如果 I 和 J 访问不同的数据项,那么我们可以交换 I 和 J 的顺序而不影响结果。

  2. 如果 I 和 J 访问相同的数据项:

    • 如果 I=read(Q),J=read(Q),则顺序不重要。
    • 如果 I=read(Q),J=write(Q),则顺序重要。
    • 如果 I=write(Q),J=read(Q),则顺序重要。
    • 如果 I=write(Q),J=write(Q),则顺序重要。

我们说 I 和 J 冲突,如果它们访问相同的数据项,并且至少其中一个是写操作。

简而言之,当两个指令访问不同的数据项时,它们可以交换顺序。但当它们访问相同的数据项时,如果至少有一个是写操作,它们的顺序就变得重要,因为可能存在冲突。

冲突可串行化(Conflict Serializability)

如果一个调度 S 可以通过一系列交换连续的非冲突指令转换为调度 S',那么我们说 S 和 S' 是 "conflict equivalent" 或者称为 "冲突等价"。这意味着这两个调度是可以互换的。

如果把一个调度S中的不冲突命令调换位置后,可得到一个串行调度,那么这个调度S是“冲突可串行化”

冲突可串行化的判断

"Precedence graph"(优先关系图)是一个有向图,其中顶点表示事务,如果两个事务发生冲突且 Ti 在 Tj 之前访问了数据项,我们就在图中从 Ti 到 Tj 画一条弧。一个调度是冲突可串行化的,当且仅当它的优先关系图是无环的。

image.png 如果优先关系图是无环的,那么可以通过找到与优先关系图的偏序一致的线性顺序来获得串行化顺序。这个过程被称为拓扑排序。

image.png

概念对比与总结

Serial Schedule (串行调度): 在串行调度中,事务按顺序一个接一个地执行,没有交错。这意味着一个事务完成执行后,下一个事务才开始执行。

Serializable Schedule (可串行调度): 可串行调度是指一个事务调度的执行结果与某个串行调度的执行结果等价。换句话说,虽然事务可能是并发执行的,但系统的状态转换与某个串行执行的状态转换是相容的。

Conflict Serializable Schedule (冲突可串行调度): 冲突可串行调度是可串行调度的一个特例,其中事务之间的冲突关系与某个串行调度的冲突关系相对应。冲突关系通常涉及对相同数据项的读/写操作,因此冲突可串行调度确保在并发执行中保持与串行执行相容的结果。这有助于维护数据库的一致性。

可恢复调度(Recoverable Schedules)

假设有两个事务,分别为T8和T9。

T9依赖于T8,这意味着T9的执行受到T8的影响。

如果T8发生了中断(abort),那么必须也中断(abort)T9。这是因为T9依赖于T8的执行结果,如果T8没有成功完成,T9可能无法正确执行。

image.png

如果 Y 读了 X 修改过的数据,那么在 X 提交后,Y 才能提交

连锁回滚(Cascading Rollbacks)

如果T10失败,那么T11和T12也必须回滚。

连锁回滚是指一个事务的失败导致一系列事务的回滚。

连锁回滚是不可取的,因为它会导致大量工作的撤销。这是因为除了失败的事务(T10)之外,还需要回滚与之相关的其他事务(T11和T12),这可能导致系统中较大范围的数据撤销和一致性问题。

image.png

无连锁回滚的调度

在 X 提交后,Y 才能读 X 修改过的数据,无连锁回滚调度一定是可恢复调度