存储过程异常处理存在问题:触发异常时未正确删除指定数据
分析与解决存储过程异常处理问题
我来帮你一步步排查这个存储过程的问题,核心问题主要出在异常处理的逻辑顺序和细节错误上:
问题1:ROLLBACK执行时机错误,导致DELETE操作无效
当异常触发时,你首先执行了ROLLBACK;,这会直接回滚所有未提交的DML操作:
- 如果异常发生在
INSERT INTO TABLE1之后、INSERT INTO TABLE2之前,ROLLBACK会撤销TABLE1的插入记录; - 如果异常发生在
INSERT INTO TABLE2之后,ROLLBACK会同时撤销TABLE1和TABLE2的插入记录。
此时数据库中根本不存在对应SEQ1或SEQ2的记录,后续的DELETE操作自然不会有任何效果。
问题2:TABLE2的DELETE条件使用了错误的序列值
代码中DELETE FROM TABLE2 WHERE COLUMN0 = SEQ1;是明显的笔误:TABLE2的插入是用SEQ2作为主键的,这里应该使用SEQ2才对。不过这个问题在ROLLBACK之后已经无关紧要,因为ROLLBACK已经把TABLE2的插入操作回滚了。
修正后的存储过程代码
既然ROLLBACK会自动回滚所有未提交的操作,我们完全不需要手动执行DELETE,修正后的代码如下:
PROCEDURE TEST (TEST IN TABLE1.COLUMN1%TYPE, TEST2 IN TABLE2.COLUMN1%TYPE) IS SEQ1 NUMBER; SEQ2 NUMBER; BEGIN SELECT seq_id.NEXTVAL INTO SEQ1 FROM DUAL; INSERT INTO TABLE1 VALUES(SEQ1, TEST); SELECT seq_id2.NEXTVAL INTO SEQ2 FROM DUAL; INSERT INTO TABLE2 VALUES(SEQ2, TEST2); COMMIT; EXCEPTION WHEN OTHERS THEN -- 回滚所有未提交的插入操作,无需手动DELETE ROLLBACK; RAISE; END;
额外说明
如果你的业务场景中存在部分已提交的操作(比如调用了其他包含COMMIT的存储过程),那需要单独针对已提交的数据做手动清理,但在当前代码中,所有操作都处于同一个事务中,COMMIT放在最后执行,所以ROLLBACK足以撤销所有未完成的修改。
内容的提问来源于stack exchange,提问作者Popplar
相关产品推荐
相关产品推荐

