那么 Oracle 异常处理程序中的 `ROLLBACK` 与我的 `ROLLBACK` 有何不同?

So how is `ROLLBACK` in Oracle exception handler different from my `ROLLBACK`?

Oracle 数据库如何回滚到 PL/SQL 块的开头,而不是更早的 DML 指令(我认为所有这些都属于一个事务)。因为当我尝试 ROLLBACK 创建异常处理程序时,直到最后 COMMIT 的所有指令都被回滚。

create table mytable (num int not null primary key);

insert into mytable values(1); // My ROLLBACK, rollbacks to here.

begin       // Oracle exception handler rollbacks to here.
insert into mytable values(3);
  begin
   insert into mytable values(2);
   insert into mytable values(1);
  end;
  /* Incase I  try to ROLLBACK all the updates including the first insert is gone.*/
  --exception when dup_val_on_index then
  --rollback;
end;

最终table数据:
1) Incase of oracle 处理异常

mytable 
_______
1

2) Incase of oracle 处理异常

mytable 
_______

那么 Oracle 异常处理程序中的 ROLLBACK 与我的 ROLLBACK 有何不同。

将任何 DML 语句视为原子事务,您将 BEGIN ... END 中的多个语句分组为原子事务,并且内部的异常将导致此块中的语句回滚。 使用 SAVEPOINT 更好地处理回滚情况。

这就是 Oracle 的工作原理。您的第一个 INSERT 已正确完成(即将“1”插入 table)。

然后你 运行 一个匿名 PL/SQL 块插入“3”,然后插入“2”,并且由于主键冲突而尝试插入“1”时失败。

如果在执行那个 PL/SQL 块期间发生未处理的异常(这就是你所说的 "Oracle exception handler rollbacks to here"),Oracle 将回滚到 PL/SQL 块的开头。

当您使用 EXCEPTION 处理程序并发出 ROLLBACK 时,如果发生某些事情,则由您来决定要做什么,那就是将所有更改恢复到先前的 COMMIT,这是在执行 CREATE [=23 之后隐式完成的 COMMIT =] 语句,所以后面的 INSERT "1" 也回滚了。