在Oracle中使用事务的Savepoints进行保存事务点。Savepoint将一个长事务分隔为较小的部分。 使用savepoint,可以在长事务中任何点任意事务点标记操作。然后可以选择回滚在事务中当前点之前、声明的savepoint之后执行的操作。Savepoints也可应用于程序中,如果一个过程包含几个函数,那可以在每个函数前创建一个savepoint。如果一个函数失败,返回数据到函数开始前的状态并在修改参数或执行一个恢复操作后重新运行函数就非常容易。在回滚到一个savepoint后,Oracle释放由被回滚的语句持有的锁。其他等待之前被锁资源的事务可以进行了。其他要更新之前被锁行的事务也可以执行。
当一个事务回滚到一个savepoint,发生下列事件:
1. Oracle仅回滚savepoint之后的语句。
2. Oracle保留这一savepoint,但所有建立于此后的savepoints丢失。
3. Oracle释放在该savepoint后获得的所有表、行锁,但保留之前获得的所有锁。
事务保持活动并可继续。 无论何时一个会话在等待事务,到savepoint的回滚不会释放行锁。为了确保事务如果无法获得锁也不会悬挂,
在执行UPDATE或DELETE前使用FOR UPDATE NOWAIT。
注意事项:
1.savepoint名字保持唯一
2.如果后面新设置的一个savepoint的名字和前面的一个savepoint名字重复,前一个savepoint将被取消
3.设置savepoint后,事务可以继续commit,全部回退或者回退到具体一个savepoints
4.撤销的处理必须是在没有发出commit命令的前提下才能有效。
当一个事务回滚到一个savepoint,发生下列事件:
1. Oracle仅回滚savepoint之后的语句。
2. Oracle保留这一savepoint,但所有建立于此后的savepoints丢失。
3. Oracle释放在该savepoint后获得的所有表、行锁,但保留之前获得的所有锁。
事务保持活动并可继续。 无论何时一个会话在等待事务,到savepoint的回滚不会释放行锁。为了确保事务如果无法获得锁也不会悬挂,
在执行UPDATE或DELETE前使用FOR UPDATE NOWAIT。
注意事项:
1.savepoint名字保持唯一
2.如果后面新设置的一个savepoint的名字和前面的一个savepoint名字重复,前一个savepoint将被取消
3.设置savepoint后,事务可以继续commit,全部回退或者回退到具体一个savepoints
4.撤销的处理必须是在没有发出commit命令的前提下才能有效。
DECLARE
BEGIN
SAVEPOINT a_work;
INSERT
INTO dj_forwarder_info_tab (
forwarder_no,--主键
cust_description,
description,
tel,
fax,
link_man,
email,
msn,
note_text,
rowversion)
VALUES (
'A',
'test',
'test',
'test',
'test',
'test',
'test',
'test',
'test',
SYSDATE);
---
INSERT
INTO dj_forwarder_info_tab (
forwarder_no,
cust_description,
description,
tel,
fax,
link_man,
email,
msn,
note_text,
rowversion)
VALUES (
'A',----主键重复添加A,发生错误
'test',
'test',
'test',
'test',
'test',
'test',
'test',
'test',
SYSDATE);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
ROLLBACK TO a_work; ---回滚事务,添加不成功
COMMIT;
END Import_Inv_Part;