数据库服务器使用以下过程修改一条特定记录中包含的信息。与插入相同,所有事务都将执行以下一系列的操作,而无论其隔离级别为何。
在表上获取共享模式锁(如果尚未持有)。
在表上获取意图写表锁(如果尚未持有)。
标识要更新的候选行。当扫描行时,将它们锁定。缺省锁定行为如隔离级别和一致性所述。
在隔离级别 2 和 3,会出现与缺省锁定行为不同的以下差异:将获取意图写行级锁定而非读锁定,并且在某些情况下可能会在最终被拒绝作为更新候选行的行上获取意图写锁定。
对于在步骤 2.a 中标识的每个候选行,遵循其余的顺序。
在受影响的行上放置写锁定。
按照每个 UPDATE 语句,更新每个受影响的列值。
如果索引值被更改,请添加新索引条目。会保留行的原始索引条目,但会将其标记为已删除。持有长期插入锁时插入新值的新索引条目。服务器将校验索引唯一性(如果适当)。
如果对行中的任何外键值进行了变更,则会在主表上获取一个共享模式锁,并按照插入过程中的锁定中概述的插入新外键值的过程进行操作。同样,按照 WAIT_FOR_COMMIT 的过程进行操作(如果适用)。
如果该表是参照完整性关系中的主表,且关系的 UPDATE 操作不是 RESTRICT,则确定外表中受影响的行(通过以下操作:首先在外表上获取共享模式锁,然后在每个表上获取意图写表锁),然后在所有受影响的行上获取写锁定,并根据需要修改各行。请注意,此过程可能分多级进行参照完整性约束的嵌套层次。
最后一步之后,任何 AFTER UPDATE 触发器都可能触发。COMMIT 后,服务器将通过确保此事务生成的遗孤数为 0 来验证参照完整性,并释放所有的锁。
修改列值可能需要执行大量操作。如果您要修改的列不属于主键或外键,数据库服务器需要完成的工作量会少得多。如果要修改的列不包含在索引中(此索引或显式创建,或因为您已将该列声明为唯一的而隐式创建),需要完成的工作量还会更少。
UPDATE 操作过程中的参照完整性校验操作并不比 INSERT 过程中的校验操作简单。实际上,更改主键的值时,就可能会产生遗孤。插入替换值时,数据库服务器必须再次检查是否产生了遗孤。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |