Using rollback and savepoint commands to control transaction in Oracle Forms
should be avoided from the following reasons.
- Savepoints are a crucial part of an Oracle transaction
- And they are especially important for a Forms transaction
- The reason is Forms uses savepoints for it's internal processing
- And the Forms transaction must never be desynchronized with the database
To guarantee the consistency of the Forms processing don't try to set a
savepoint of your own. It won't work anyway or it will break your application.
Here are some examples:
1) If you do this in PL/SQL in Forms:
ROLLBACK to my_savepoint;
Forms will not rollback to my_savepoint.
It will rollback to it's own savepoint.
This could be the savepoint defined when the starting the app,
or before starting the commit processing. When calling a new form
with CALL_FORM a savepoint is set too. This savepoint is not set
with OPEN_FORM. So a ROLLBACK TO <savepoint> in this case will
be a rollback of the entire application.
2) If you use a ROLLBACK TO <savepoint> in a stored program
unit, Forms doesn't see this. So you could rollback a part
of the database transaction without rolling back the
correlated part of the Forms transaction. Forms transaction
processing has very closely tied to the database transaction
processing. So be always very careful in this area.
3) The example for ISSUE_SAVEPOINT is in the Forms 6.0 Reference
Manuel, page 275. It shows an ON-SAVEPOINT trigger used for
running against a third party database without savepoints or
with a savepoint processing different from the Oracle
processing. If Forms runs with an Oracle database it uses
the default processing, if not is uses a user exit.
Here some rules we should follow:
- Don't use the SAVEPOINT or ROLLBACK TO <savepoint> commands
in Forms. You won't achieve what you want.
- Don't use SAVEPOINT, ROLLBACK TO <savepoint>, ROLLBACK or
COMMIT in stored program units. You'll desynchronize Forms
and the database. There is an exception to this rule
which will be explained later.
- Don't use ISSUE_SAVEPOINT and ISSUE_ROLLBACK other than
the documented way.
Here is the exception to the second rule which might provide
a solution for your problem. If you really need
a ROLLBACK or a COMMIT in a stored program unit, because
you cannot have it in local PL/SQL, do this:
- call a new Form with OPEN_FORM(...,SESSION)
- from this form call the stored program unit
So you have a different transaction. Everything you do there
doesn't hurt the existing Forms transaction. Just ensure
that you don't use any Forms default transaction processing
in this second transaction.
But in most cases you could do the same thing with a second
transaction and Forms default processing. What was designed
to be a rollback to savepoint first, could here be designed
as a full rollback of the second transaction. This is another
rule you always should keep in mind when programming with Forms:
Always try to use Forms default processing:
- otherwise you have to do much more coding
- in most cases the default processing is faster than programmed
无论何时一个会话在等待事务，到savepoint的回滚不会释放行锁。为了确保事务如果无法获得锁也不会悬挂（hang），在执行UPDATE或DELETE前使用FOR UPDATE ... NOWAIT。（这里指回滚的savepoint之前获得的锁。该savepoint后获得的行锁会被释放，之后执行的语句也会被彻底回滚。）