4.4.6 事务中对完整性约束的违反

4.4.6 事务中对完整性约束的违反

事务可能包括几个步骤,在某一步之后完整性约束也许会暂时被违反,但是后面的某一步也许就会消除这个违反

例如,假设我们有一个主码为nameperson关系,还有一个属性是ouse,并且spouse是在person上的一个外码。也就是说,约束要求spouse属性必须包含在person表里出现的名字假设我们希望在上述关系中插入两个元组,一个是关于John的,另一个是关于Mary的,这两个元组的配偶属性分别设置为MaryJohn,以此表示JohnMary彼此之间的婚姻关系。无论先插入哪个元组,插入第一个元组的时候都会违反外码约束。在插入第二个元组后,外码约束又会满足了

1. 延迟约束检查到事务结束时

为了处理这样的情况,SQL标准允许将initially deferred子句加入到约束声明中;
这样完整性约束不是在事务的中间步骤上检查,而是在事务结束的时候检查
一个约束可以被指定为可延迟的(deferrable),这意味着默认情况下它会被立即检查,但是在需要的时候可以延迟检查。
对于声明为可延迟的约束,执行set constraints constrain-list deferred语句作为事务的一部分,会导致对指定约束的检查被延迟到该事务结束时执行
然而,读者应该注意的是默认的方式是立即检查约束,而且许多数据库实现不支持延迟约束检查

2. 通过设置null来让事务不违反完整性约束

如果spouse属性可以被赋为null,我们可以用另一种方式来避开在上面例子中的问题:
在插入JohnMary元组时,我们设置其spouse属性为null,然后再更新它们的值。然而,这个技术需要更大的编程量,而且如果属性不能设为null的话,此方法就不可行。