6.10 自测题答案
(1) 答案为B、C、D和F。它们都是DML命令。它们都可以回滚。
A和E是错误的。COMMIT命令终止事务,不能回滚它。TRUNCATE命令是DDL命令,它包含内置的COMMIT命令。
(2) 答案为C。这是所期望的行为:回滚语句,事务的余下部分保持未提交状态。
A、B和D是错误的。A是错误的,因为虽然这种行为实际上可配置,但在默认情况下没有启用它。B是错误的,因为虽然在空间错误的情况下这是可能的,但在默认情况下没有启用它。D是错误的,因为只回滚一条语句,而不是整个事务。
(3) 答案为D。语法是错误的:使用VALUES关键字或者子查询,但不能同时使用两者。删除VALUES关键字,它就会运行。C3和C4由NULL填充。
A、B、C和E是错误的。A是错误的,因为不需要为没有列出的列提供值。B和C是错误的,因为INSERT可以插入一组行,因此不需要使用WHERE子句来限制行数,或者使用MAX或MIN让它只返回一行。 E是错误的,因为语句在语法上是不正确的。
(4) 答案为A。这是一种最简单(因此也是最好)的方法。
B、C和D是错误的。所有这些语句都会运行,但它们都过于复杂。没有编程人员会使用不必要的语句。
(5) 答案为A和C。TRUNCATE更快,但DELETE也能完成这项任务。
B和D是错误的。B是错误的,因为它会删除表以及表内的行。D是错误的,因为行仍然会存在——虽然用NULL填充它们。
(6) 答案为B。隔离性原则说明只有JOHN能够看到他未提交的事务。
A、C和D是错误的。A是错误的,因为事务隔离性意味着其他会话都无法看到这些变更。C和D是错误的,因为不可能回滚已经提交的事务。
(7) 答案为C、B、D和A。这是正确的顺序,其他顺序都不对。
(8) 答案为C。通过在日志缓冲区放置COMMIT记录,并由LGWR将日志缓冲区刷新到磁盘来实现COMMIT。
A、B和D是错误的。A是错误的,因为很多变更向量(或许是全部)已经写入磁盘。B是错误的,因为DBWn不参与提交处理。D是错误的,因为撤消数据完全可能持久保存一段时间,COMMIT与此无关。
(9) 答案为A、B和D。对其中任一项的更改都将生成重做。
C是错误的,对临时段的更改不生成重做。
(10) 答案为A和B。DDL和访问控制命令都包括COMMIT。
C和D是错误的。C之所以错误,是因为保存点只不过是事务中的标记。D是错误的,因为这是仅本地作用于用户进程的SQL*Plus命令,对活动事务没有任何影响。
(11) 答案是B。默认情况下,行独占锁禁止写入行,但不禁止读取行。
A、C和D是不正确的。A是不正确的,因为永远可以读取更新的行(采用其预更新的形式)。C是不正确的,因为阻塞的是DML,而不是COMMIT。D是不正确的,因为默认的互斥锁只存在于受影响的行上。
(12) 答案是E。阅读器永远不会阻塞。
A、B、C和D是不正确的。A是不正确的,因为它禁止更新所有行,B是不正确的,因为它将锁定任何已更新的行。但不会阻塞阅读器。C和D是不正确的,因为它们将共享锁放在表上,将排他锁放在行上。同样,不会阻塞阅读器。
(13) 答案为C。它正确描述了排队机制的操作。
A、B和D是不正确的。A是错误的,因为锁定按顺序授予,并非随机授予。B是错误的,因为共享锁应用于对象,行锁必须是排他锁。D是错误的,因为这更像是在描述死锁的管理方式。
(14) 答案是D。它正确描述了DML锁定机制:共享锁保护表定义,排他锁保护行。
A、B和C是不正确的。A是不正确的,因为锁总是强加的。B是错误的,因为只有程序员请求,才应用排他表锁。C是错误的,因为排他锁必须总是放在行上。
(15) 答案是A。一个语句将自动回滚,允许会话继续进行。
B、C、D和E是不正确的。B是不正确的,因为只有一条语句会回滚。另一条语句仍有效,阻断其会话。C是不正确的,因为这就是要避免的结果。D和E是不正确的,因为死锁处理机制不会终止会话,只终止语句。
(16) 答案为C。所有DML都出现在数据库缓冲区缓存中,对数据块和撤消块的更改都受到重做的保护。
A、B和D是不正确的。A是错误的,因为对磁盘的写入与执行语句无关。B和D是不正确的,因为B和D的描述不完整:重做将保护对数据块和撤消块的更改。
(17) 答案是D。所有DML都会生成撤消记录,所以减少撤消记录的生成的唯一方法是重新设计应用程序。
A、B和C是不正确的。A是不正确的,因为尽管自动撤消更有效率,它不能减少撤消记录。B是不正确的,因为没有参数设置可以关闭撤消。C是错误的,因为段的大小只影响它们重用的速度,不影响生成的撤消量。
(18) 答案是C、D和F。C是正确的,因为撤消在提交时,会变得不活跃 (尽管它不一定到期)。D是正确的,因为查询需要撤消数据,才能构建数据状态与查询刚开始时一致的结果。F是正确的,因为Oracle保证查询内部的一致性,不保证跨查询的一致性。
A、B和E是不正确的。A是不正确的,因为Oracle保证查询内部的一致性,不保证跨查询的一致性。B是不正确的,因为COMMIT提交和写入数据文件之间没有相关性。E是不正确的,因为第二个查询针对的是查询过程中没有改变的表。
(19) 答案是B。扩展为一个事务的撤消段会产生更多的撤消数据。
A、C和D是不正确的。A是不正确的,因为只有并发事务比段更多,才创建另一个撤消段。C混淆了段被填满了的效果和表空间被填满了的效果。D是不可能,因为一个撤消段只能保护一个事务。
(20) 答案是A、C和E。A是正确的,但Oracle会尽量避免这种情况。C是正确的,但实例在任何时刻只激活一个撤消段。E是正确的,因为当涉及存储时,撤消段就像任何其他段一样:表空间从逻辑存储中抽象出物理存储。
B、D和F是不正确的。B是不正确的,因为一个撤消段只能保护一个事务。D是不正确的,因为一个实例只能使用一个撤消表空间。F是错误的,因为撤消和回滚段可以共存,但数据库只能使用其中一个。
(21) 答案是A。根据需求创建撤消段。
B、C和D是不正确的。B是不正确的,因为会创建更多的段。C是不正确的,因为撤消段的数量没有限制。D是不正确的,因为这个参数与事务不相关,只与查询相关。
(22) 答案是C。“ORA - 1555:快照太旧”错误清楚地表明,撤消数据不会保存足够长的时间,来满足查询工作负载。没有足够的撤消数据可用。
A、B和D是不正确的。A是不正确的,因为它根本没有引用撤消,而是引用了快照,它存在于数据库的早期版本中,但现在称为物化视图。B和D都是不正确的,因为它们描述了在相反的情况下,撤消数据保留的时间超过了需要的时间。这不是一个问题,但它可能会浪费空间。
(23) 答案为C。在计算时,使用为期10分钟的UNDBLKS最大值。除以600得到每秒钟的撤消块生成率,并乘以块大小得到字节值。再乘以MAXQUERYLEN的最大值,得到需要的空间(如果最高撤消生成率与时间最长的查询一致),除以十亿得到GB结果:237 014/600×4096×1740 = 2.6GB(近似值)。
A、B和D是错误的。这些数字来自于对撤消计算的不正确理解(详见C的解释)。
(24) 答案是A、B、C和D。对所有数据块的更改由重做数据保护。回滚操作会更改块,因此也会产生重做数据。
E和F是不正确的。COMMIT不写入更改,因为它们已经写入了。查询从来不读写重做数据,但它们很可能读取撤消数据。
(25) 答案是C、D和E。C是正确的,因为使查询更快完成,将减少“快照太旧”的可能性。D是正确的,因为它允许存储更多未到期的撤消数据。E完整地解决了问题,但可能会导致事务出问题。
A、B和F是不正确的。A是不正确的,因为它本身没有帮助,它只是一个目标,除非结合E。B是不正确的,因为没有这样的参数(但它是一个子句,可以应用于撤消表空间)。F是不正确的,因为这不能手工完成,Oracle会自动完成。