Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 提交和回滚的时间是否会影响性能?_Oracle - Fatal编程技术网

Oracle 提交和回滚的时间是否会影响性能?

Oracle 提交和回滚的时间是否会影响性能?,oracle,Oracle,假设我有一套身份证。对于每个ID,我将根据ID向许多不同的表插入许多记录。在插入不同的表之间,将调用不同的业务检查。如果任何检查失败,将回滚基于此ID插入的所有记录。此批量插入操作通过使用PL/SQL完成。提交和回滚的时间会影响性能吗?它是如何影响性能的?例如,我应该在完成流程后提交一个ID还是在完成所有ID后提交?这与其说是一个性能决策,不如说是一个流程设计决策。当您必须回滚错误的ID时,是否希望其他ID保留在数据库中 由于明显的原因,当必须回滚更多行时,回滚需要更长的时间。回滚通常比必须回滚

假设我有一套身份证。对于每个ID,我将根据ID向许多不同的表插入许多记录。在插入不同的表之间,将调用不同的业务检查。如果任何检查失败,将回滚基于此ID插入的所有记录。此批量插入操作通过使用PL/SQL完成。提交和回滚的时间会影响性能吗?它是如何影响性能的?例如,我应该在完成流程后提交一个ID还是在完成所有ID后提交?

这与其说是一个性能决策,不如说是一个流程设计决策。当您必须回滚错误的ID时,是否希望其他ID保留在数据库中


由于明显的原因,当必须回滚更多行时,回滚需要更长的时间。回滚通常比必须回滚的操作花费更长的时间(有时更长!)。在Oracle中,提交总是很快的,因此在这方面,您提交的频率可能并不重要。

不要让事务花费更长的时间。尽量简短。因为根据您的查询,已经创建了一些锁。此锁定可能会导致性能问题。。。所以,一个ID一个ID地做这件事。

有两种“力量”在起作用

  • 锁定 在打开的事务期间,oracle将锁定更改的行。 每当其他事务需要更新任何锁定的行时, 它必须等待。 在最坏的情况下,甚至可以构建死锁

  • 同步写入 每次提交都执行同步写入。 (有很多方法可以禁用它,但这通常是每个人都想要的:诚信)。 同步写入可能比常规写入(可以缓冲)所需的时间更长。 不要忘记,提交通常会涉及额外的网络往返

  • 因此,一种力量说“尽快提交(考虑到您的完整性要求)”,另一种力量说“尽可能少地提交”

    <> P>还有一些其他问题需要考虑,例如最大事务大小。每个未限制的事务都需要一些临时空间。交易越大,你需要的就越多。您还可能遇到ORA-01555“快照太旧”


    如果有任何建议可以给出,那么就是实现一个可配置的“提交频率”,以便您可以根据需要轻松地更改它。

    您的问题描述表明您有一大组较小的逻辑事务(每个新ID都是一个事务)。您应该提交每个逻辑事务。等待提交整个事务集的两个原因是:

  • 如果整个事务集实际上是一个事务本身,则所有插入都必须成功才能提交任何行。在这种情况下,较小的“事务”并不是真正的事务
  • 在批量加载过程中没有重新启动功能,这实际上是第1项的特例。如果批量加载过程中止,则需要一种跳过成功应用的ID的方法
    Tom Kyte的建议是提交每个逻辑工作单元-事务。

    如果需要控制单个集合,但保留提交或回滚整个事务的能力,则可以选择使用保存点。您可以在最外层循环的开始处设置保存点,然后在发生错误时回滚到该保存点。你可能会得到这样的结果:

    begin
       --Initial batch logging
       for r_record in cur_cursor loop
          savepoint s_cursor loop;
          begin
             --Process rows
          exception
             when others then
                rollback to s_cursor;
          end;
       end loop;
       --Final batch logging
    exception
       when others then
          rollback;
          raise;
    end;
    

    1) 如果您经常提交,则更有可能遇到ORA-1555,请参阅。2) 死锁始终是一个开发缺陷,因为在更新行之前可以使用SELECT FOR UPDATE NOWAIT来防止死锁。Tom Kyte在他的书《专家一对一Oracle》中指出,您不需要通过更频繁地提交来保存任何内容,事实上,这样做需要更多的CPU、更多的磁盘,而且[最重要的是]更多的编程。OP说他们正在插入,所以不应该有任何锁(由更新引起)。但是,在任何唯一的索引值上都有锁。任何试图插入副本的其他事务都将等待原始事务提交或回滚。也可能存在与外键约束有关的锁。引用另一个表中现有行的新行可防止更新或删除会使新行中的外键无效。永远不要低估外键约束的锁定能力!另一个大问题是完整性——一旦您提交,其他会话就可以看到数据。这就增加了查询一组破坏完整性的数据的可能性,因为只有一部分更改。在所有表中的所有更改之后进行一次提交可确保完整性。“破坏完整性”是一个糟糕的词语选择——您不能从违反约束的意义上破坏Oracle完整性。我认为这里的意思是,如果您的逻辑事务是1M行,并且每100K行提交一次,那么在提交最后100K行之前,数据在逻辑上变得不一致;你只需要禁用一个约束,违反它,然后用NOVALIDATE子句启用它。现在为什么我没有想到呢?不幸的是,在Oracle中提交并不总是很快的。可能存在日志切换等问题。