SAVEPOINT(保存点)是事务处理过程中的一个标志,与回滚命令(ROLLBACK)结合使用,主要的用途是允许用户将某一段处理回滚而不必回滚整个事务,这在PL/SQL开发中还是很有用处的。以下模拟两种情况:
一. 开发环境。
模拟代码:DECLARE
l_err_code number := 0; --catch exception in DML BLOCK
BEGIN
savepoint savepoint_test;
--DML BLOCK BEGIN
……
--DML BLOCK END
if l_err_code != 0 then
rollback to savepoint_test;
else
commit;
end if;
END;
二. 修改情况(业务更改,增加或源程序发生bug,需要修改等)
模拟代码:DECLARE
l_err_code number := 0; --catch exception in DML BLOCK
BEGIN
savepoint savepoint_test;
--DML BLOCK BEGIN
--ALTER DML BEGIN
……
COMMIT;
--ALTER DML END
--NEW DML BLOCK BEGIN
……
COMMIT;
--NEW DML BLOCK END
--DML BLOCK END
if l_err_code != 0 then
rollback to savepoint_test;
else
commit;
end if;
END;
以上蓝色部分或者红色部分的COMMIT,会导致ORA-01086: savepoint "string" never established。
总结:一,开发阶段,编码者常常不会忘记savepoint建立点和回滚代码之间不能COMMIT。
二,原程序在上线后或者上线前(经历了长时间后),由编码者或者其他同事进行修改时,容易忽视savepoint的存
在,从而导致键入了COMMIT。
同时,测试时,没有发生error,导致bug没有暴露。容易成为上线后的隐含bug。
把蓝色sql语句换成动态sql 大家可以试试
不知道大家有没有碰到过这种情况呢?本人和身边一位同事亲身经历了,呵呵~~