我应该回滚失败的 SELECT 语句还是提交成功的语句?
Posted
技术标签:
【中文标题】我应该回滚失败的 SELECT 语句还是提交成功的语句?【英文标题】:Should I rollback failed SELECT statements or commit successful ones? 【发布时间】:2011-01-23 17:33:39 【问题描述】:出于习惯,我一直在我的应用程序代码中对所有 SQL 查询使用 try/catch 块,并在 catch 块的开头进行回滚。我也一直在提交那些成功的。 SELECT
s 有必要这样做吗?它是否在数据库端释放了一些东西? select 语句没有改变任何数据,所以看起来有点毫无意义,但也许有一些我不知道的原因。
例如
try
$results = oci_execute($statement)
oci_commit($connection);
return $results;
catch
oci_rollback($connection)
throw new SqlException("failed");
【问题讨论】:
【参考方案1】:Oracle
中的SELECT
语句(除非它们是SELECT FOR UPDATE
)从不锁定任何记录,也从不隐式打开事务。
除非您在事务中发出任何DML
操作,否则您提交还是回滚事务都无关紧要。
【讨论】:
@Quassnoi:嗯,可以。如果打开游标,则将为自打开游标以来正在进行的每个事务保留回滚(UNDO)。因此,如果要打开任何记录集,则确实需要在完成后关闭它们,以帮助可怜的 DBA 避免可怕的 ORA-01555。在某些数据库系统(我在看你,DB2)中,您确实需要在选择后提交以消除读锁。这可能就是编码标准演变而来的地方,或者只是单纯的偏执狂。 @Adam:UNDO
是由其他事务生成的,而不是保留光标的事务(我们假设它是只读的)。其他事务可能会更改数据,修改数据页(在这种情况下,UNDO
将被生成并保留到事务结束)和提交(在这种情况下,UNDO
被释放并标记为可以重写)。在只读游标中,只有当游标所需的数据被提交的并发事务覆盖时,才会生成ORA-01555
。同样,游标本身不会锁定数据,不会生成任何UNDO
,甚至不会锁定它需要的UNDO
。以上是关于我应该回滚失败的 SELECT 语句还是提交成功的语句?的主要内容,如果未能解决你的问题,请参考以下文章