通常,有 3 种基于可恢复性的时间表,如下所示:
- 可恢复的时间表:
事务必须按顺序提交。可能会出现脏读问题和丢失更新问题。 - 无级联时间表:
Dirty Read not allowed,表示不允许读取未提交事务写入的数据。可能会出现丢失更新问题。 - 严格的时间表:
不允许出现脏读和丢失更新问题,这意味着不允许读取或写入未提交事务写入的数据。
脏读问题:
当一个事务从另一个事务中未提交的写入读取数据时,它被称为脏读。如果写入事务失败,则写入的数据可能会再次更新。因此,这会导致脏读问题。
换句话说,
Reading the data written by an uncommitted transaction is called as dirty read.
之所以称为脏读,是因为未提交的事务总是有可能稍后回滚。因此,未提交的事务可能会使其他事务读取一个甚至不存在的值。这会导致数据库的不一致。
例如,假设事务 1 更新了一行并使其未提交,同时事务 2 读取更新后的行。如果事务 1 回滚更改,事务 2 将读取被认为从未存在的数据。
请注意,没有脏读问题,是一个事务正在从另一个提交的事务中读取。所以,不需要回滚。
级联回滚:
如果在一个调度中,一个事务的失败导致其他几个相关事务回滚或中止,那么这种调度称为级联回滚或级联中止或级联调度。它只会导致 CPU 时间的浪费。
这些级联回滚是由于脏读问题而发生的。
例如,事务 T1 写入事务 T2 读取的未提交 x。事务 T2 写入事务 T3 读取的未提交 x。
假设此时 T1 失败。
T1必须回滚,因为T2依赖T1,T2必须回滚,T3依赖T2,T3必须回滚。
因为T1回滚,所有T2、T3、T4也应该回滚(Cascadingdirty read问题)。
这种由单个事务失败导致一系列事务回滚的现象称为级联回滚。
无级联时间表:
这个调度避免了所有可能的脏读问题。
在 Cascadeless Schedule 中,如果一个事务要对一个值执行读操作,它必须等到对该值执行写操作的事务提交。这意味着不能有Dirty Read 。因为脏读问题会导致级联回滚,效率低下。
Cascadeless Schedule 避免了级联中止/回滚 (ACA)。事务仅在它们要读取其更改的所有事务提交后才读取值的调度称为无级联调度。避免单个事务中止导致一系列事务回滚。防止级联中止的策略是禁止事务从同一调度中的另一个事务读取未提交的更改。
换句话说,如果某个事务 Tj 想要读取某个其他事务 Ti 更新或写入的值,那么 Tj 的提交必须在 Ti 提交之后读取它。
请注意,无级联调度只允许提交的读操作。但是,它允许未提交的写操作。
还要注意,Cascadeless Schedules 总是可恢复的,但所有可恢复的事务可能不是 Cascadeless Schedule。