【问题标题】:Should I rollback failed SELECT statements or commit successful ones?我应该回滚失败的 SELECT 语句还是提交成功的语句?
【发布时间】:2011-01-23 17:33:39
【问题描述】:

出于习惯,我一直在我的应用程序代码中对所有 SQL 查询使用 try/catch 块,并在 catch 块的开头进行回滚。我也一直在提交那些成功的。 SELECTs 有必要这样做吗?它是否在数据库端释放了一些东西? select 语句没有改变任何数据,所以看起来有点毫无意义,但也许有一些我不知道的原因。

例如

try {
  $results = oci_execute($statement)
  oci_commit($connection);
  return $results;
}
catch {
  oci_rollback($connection)
  throw new SqlException("failed");
}

【问题讨论】:

    标签: php sql oracle transactions rollback


    【解决方案1】:

    Oracle 中的SELECT 语句(除非它们是SELECT FOR UPDATE)从不锁定任何记录,也从不隐式打开事务。

    除非您在事务中发出任何DML 操作,否则您提交还是回滚事务都无关紧要。

    【讨论】:

    • @Quassnoi:嗯,可以。如果打开游标,则将为自打开游标以来正在进行的每个事务保留回滚(UNDO)。因此,如果要打开任何记录集,则确实需要在完成后关闭它们,以帮助可怜的 DBA 避免可怕的 ORA-01555。在某些数据库系统(我在看你,DB2)中,您确实需要在选择后提交以消除读锁。这可能就是编码标准演变而来的地方,或者只是单纯的偏执狂。
    • @Adam:UNDO 是由其他事务生成的,而不是保留光标的事务(我们假设它是只读的)。其他事务可能会更改数据,修改数据页(在这种情况下,UNDO 将被生成并保留到事务结束)和提交(在这种情况下,UNDO 被释放并标记为可以重写)。在只读游标中,只有当游标所需的数据被提交的并发事务覆盖时,才会生成ORA-01555。同样,游标本身不会锁定数据,不会生成任何UNDO,甚至不会锁定它需要的UNDO
    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 2021-08-21
    • 2020-11-02
    • 1970-01-01
    • 2011-03-04
    • 2011-12-31
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多