savepoint(回退点)

什么是savepoint?
Use 
the SAVEPOINT statement to identify a point in a transaction to which you can 

later roll back.

使用检查点语句标识一个事务点以便在后面可以回滚。

语法:SAVEPOINT savepoint ;

事例:

1)首先看一下员工表中Banda的工资

SQL> select employee_id, last_name, salary from employees where last_name='Banda';

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        167 Banda                           6200

 

2)我们来修改一下Banda的工资并创建检查点banda_sal:

SQL> update employees
  2     set salary = 7000
  3     where last_name ='Banda';

已更新 1 行。

SQL> savepoint banda_sal;

保存点已创建。

3)再对Banda的工资做一次修改并创建检查点banda_sal2:

SQL> update employees
  2     set salary = 8000
  3     where last_name ='Banda';

已更新 1 行。

SQL> savepoint banda_sal2;

保存点已创建。

SQL> select employee_id, last_name, salary from employees where last_name='Banda';

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        167 Banda                           8000

4)下面进行回退操作,使回退到检查点banda_sal:

SQL> rollback to savepoint banda_sal;

回退已完成。

SQL> select employee_id, last_name, salary from employees where last_name='Banda';

EMPLOYEE_ID LAST_NAME                     SALARY
----------- ------------------------- ----------
        167 Banda                           7000

事务中的Savepoints 
你可以在事务上下文中声明称为savepoint的中间标记。Savepoint将一个长事务分隔为较小的部分。 
使用savepoint,你可以在长事务中任何点任意标记你的操作。然后你可以选择回滚在事务中当前点之前、声明的savepoint之后执行的操作。比如,你可以在一长段复杂的更新中使用savepoint,如果犯了个错,你不需要重新提交所有语句。 
Savepoints在应用程序中同样有用。如果一个过程包含几个函数,那可以在每个函数前创建一个savepoint。如果一个函数失败,返回数据到函数开始前的状态并在修改参数或执行一个恢复操作后重新运行函数就非常容易。 
在回滚到一个savepoint后,Oracle释放由被回滚的语句持有的锁。其他等待之前被锁资源的事务可以进行了。其他要更新之前被锁行的事务也可以执行。 
当一个事务回滚到一个savepoint,发生下列事件: 
1. 
Oracle仅回滚savepoint之后的语句。 
2. 
Oracle保留这一savepoint,但所有建立于此后的savepoints丢失。 
3. 
Oracle释放在该savepoint后获得的所有表、行锁,但保留之前获得的所有锁。 
事务保持活动并可继续。 
无论何时一个会话在等待事务,到savepoint的回滚不会释放行锁。为了确保事务如果无法获得锁也不会悬挂(hang),在执行UPDATE或DELETE前使用FOR 
UPDATE ... 
NOWAIT。(这里指回滚的savepoint之前获得的锁。该savepoint后获得的行锁会被释放,之后执行的语句也会被彻底回滚。) 
  

注意:
1.savepoint 
名字保持唯一
2.如果后面新设置的一个savepoint的名字和前面的一个savepoint名字重复,前一个savepoint将被取消
3.设置savepoint后,事务可以继续commit,全部回退或者回退到具体一个savepoints
(Savepoint 
names must be distinct within a given transaction. If you create a second 
savepoint with the same identifier as an earlier savepoint, then the earlier 
savepoint is erased. After a savepoint has been created, you can either continue 
processing, commit your work, roll back the entire transaction, or roll back to 
the savepoint.) 
4.撤销的处理必须是在没有发出commit命令的前提下才能有效。
如下:在commit;后执行rollback 
to savepoint失败 
SQL> SELECT * FROM SCOTT.DEPT  ;

DEPTNO 
DNAME          LOC
------ -------------- -------------
    10 
ACCOUNTING     NEW YORK
    20 RESEARCH       DALLAS
    30 
SALES          CHICAGO
    40 OPERATIONS     BOSTON
SQL> UPDATE 
SCOTT.DEPT  SET loc ='a' WHERE loc='NEW YORK';

1 row updated
SQL> 
SAVEPOINT a;

Savepoint created
SQL> UPDATE SCOTT.DEPT  SET loc ='b' 
WHERE loc='DALLAS';

1 row updated
SQL> SAVEPOINT 
b;

Savepoint created
SQL> COMMIT;

Commit complete
SQL> 
ROLLBACK TO SAVEPOINT a;

ROLLBACK TO SAVEPOINT a

ORA-01086: 
从未创建保留点 'A'

原文地址:https://www.cnblogs.com/JSD1207ZX/p/9386328.html