Oracle事务回滚失效问题:测试DELETE操作后数据未恢复
Oracle事务回滚失效及dbfiddle事务执行问题解答
一、ROLLBACK未生效的原因及正确操作方式
你的ROLLBACK没生效,核心原因几乎都是事务已被隐式提交,Oracle里这些场景会触发隐式提交:
- 执行了DDL语句(如
CREATE/ALTER/DROP),Oracle会自动提交当前所有未提交事务 - 客户端工具开启了自动提交功能(比如SQL Developer、PL/SQL Developer默认可能开启,每执行一条语句就自动COMMIT)
- 会话意外断开(不过这种情况事务会自动回滚,不会导致表为空)
正确的测试流程应该是:
- 先关闭工具的自动提交功能(不同工具设置位置不同,比如SQL Developer取消"AutoCommit"勾选)
- 执行以下语句(无需手动设置读写模式,Oracle默认就是读写事务):
-- 执行删除 DELETE FROM test; -- 此时查询当前会话的表,会看到数据已被删除(事务内的未提交修改) SELECT * FROM test; -- 执行回滚 ROLLBACK; -- 再次查询,数据应该完全恢复 SELECT * FROM test;
如果执行完DELETE后表最终为空,说明你在ROLLBACK之前,事务已经被提交了(可能是误操作COMMIT,或者触发了隐式提交)。
二、dbfiddle中事务测试的问题
dbfiddle的Oracle环境默认每段代码执行后会自动提交,且分块执行时会使用新会话,导致跨块的ROLLBACK无法关联之前的事务操作。
要在dbfiddle里测试事务,必须把所有事务相关步骤放在同一个代码块中,示例代码如下:
-- 先建表插数据并提交 CREATE TABLE test (id NUMBER, data VARCHAR2(100)); INSERT INTO test VALUES (1, 'a'); INSERT INTO test VALUES (2, 'b'); INSERT INTO test VALUES (3, 'c'); INSERT INTO test VALUES (4, 'd'); COMMIT; -- 事务测试逻辑放在同一块 DELETE FROM test; SELECT * FROM test; -- 显示空表 ROLLBACK; SELECT * FROM test; -- 显示4条原始数据
执行这个完整代码块,就能看到ROLLBACK的生效效果。
内容的提问来源于stack exchange,提问作者Manngo
相关产品推荐
相关产品推荐

