【发布时间】:2010-06-22 15:59:10
【问题描述】:
我有执行存储过程 10 次的 PHP 代码。如果一个存储过程调用失败,它应该继续,并在最后提交事务。
基本上是这样的:
$connection = getConn();
foreach($row as $i=>$j) {
$SQL = "BEGIN MYPROC.EXECUTE(:VAL1, :VAL2); END;";
$statement = OCIParse($connection, $SQL);
oci_bind_by_name($statement, 'VAL1', $row[i]['FIRSTVAL']);
oci_bind_by_name($statement, 'VAL2', $row[i]['SECONDVAL']);
$success = @OCIExecute($statement, OCI_DEFAULT);
if(!$success) {
print 'Exception in stored proc call';
}
else {
print 'Success';
}
}
oci_commit($connection);
我的问题是,如果在第 5 次存储过程调用中出现异常,是否会回滚到该点为止的所有存储过程调用?
【问题讨论】:
-
好问题。当第 5 次存储过程调用失败时,您现在会出现什么行为?
-
它没有回滚任何东西。成功的执行都在提交中。这就是我感到困惑的原因,因为在本网站的 1.10.4 (soft.buaa.edu.cn/oracle/bookshelf/Oreilly/langpkt/ch01_10.htm) 中,它表示当控制权返回给调用应用程序时,未处理的异常将被回滚。
-
这个页面的说法不同:stanford.edu/dept/itss/docs/oracle/10g/appdev.101/b10807/… 在“捕获未处理的异常”部分它指出,“未处理的异常也会影响子程序。如果您成功退出子程序,PL/SQL 会将值分配给 OUT 参数. 但是,如果您以未处理的异常退出,PL/SQL 不会为 OUT 参数赋值(除非它们是 NOCOPY 参数)。此外,如果存储的子程序因未处理的异常而失败,PL/SQL 不会回滚数据库工作由子程序完成。”
-
我不确定如何处理 PHP 和内联 PLSQL,以及它们是否被视为上述评论中性质的“子程序”,或者它们是否被视为顶级程序,在这种情况下我(假设)它会回滚?
-
Oracle 不会“为您”回滚任何内容,无论是否存在未处理的异常。自己测试一下:对表执行更新。执行第二次更新,其中某个值 = 1/0,引发异常。现在重新选择原始更新中的行 - 它仍然更改。您有责任提交和回滚您的更改。
标签: php oracle plsql transactions