1、问题的提出
无论是什么原因,如果事务Ti失败了,为保证事务的原子性我们必须撤消该事务对数据库造成的影响,即将事务Ti回滚。同时由于系统中事务的并发执行,还必须确保那些依赖于Ti的任何事务Tj(即Tj读取了由Ti所写的数据)也必须同时撤消掉(即回滚掉)。

2、问题的解决
⑴可恢复调度
如图10-6-1所示,事务T7读取了事务T6所写的数据A,如果事务T6发生故障而回滚,就有可能引起T7的回滚,因此事务T6必须在T7提交之前进行提交,才能保证调度中事务是可恢复的。

图10-6-1:调度9
为什么事务T6必须先于事务T7提交呢?原因就是,如果是事务T7先提交,而事务T6后提交,事务T6在提交的过程中发生了故障,这时候事务T6可以回滚,而事务T7已经提交成为结束的事务,因此无法回滚,这势必造成调度中的事务无法恢复,因此事务T6必须先于事务T7提交。
总上所述,对于每对事务Ti和Tj,如果Tj读取了由Ti所写的数据项,则Ti应先于Tj提交。我们把这样的调度称为可恢复调度。
⑵无级联调度
因一个事务故障导致一系列事务回滚的现象称为级联回滚,系统应该避免级联回滚。如图10-6-2所示,事务T9读取了事务T8写的数据A,事务T10读取了事务T9写的数据A,如果调度10的指令已经执行完事务T10的read(A),而这时事务T8发生了故障必须回滚,势必引起事务T9和T10的回滚。
图10-6-2:调度10
为什么我们不希望在调度中出现级联回滚的现象呢?原因很简单,就是级联回滚需要撤消大量的工作,而这是人们一般不希望发生的事情。


为了避免调度中事务的级联回滚,对于每对事务Ti和Tj,如果Tj读取了由Ti所写的数据项,则Ti必须在Tj读取之前提交。我们把这样的调度称为无级联调度。至于为什么Ti必须在Tj读取之前提交,可以用可恢复调度中讲过的思路,请大家自己思考。