The NO-UNDO keyword on temp-tables and variables
- Last Updated: April 29, 2024
- 4 minute read
- OpenEdge
- Version 12.8
- Documentation
You were instructed very early on in this book to define almost all variables
using the NO-UNDO keyword. Also, in this section's example,
the temp-tables for Customer, Order, and OrderLine are NO-UNDO. Why is this?
When you define variables, the AVM allocates what amounts to
a record buffer for them, where each variable becomes a field in
the buffer. There are in fact two such buffers, one for variables
whose values can be undone when a transaction is rolled back and
one for those that can't. There is extra overhead associated with
keeping track of the before-image for each variable that can be
undone, and this behavior is rarely needed. If you are modifying
a variable inside a transaction block (and it is important for your
program logic that sets that variable's value that it be undone
if the transaction is undone), then you should define the variable without the NO-UNDO keyword.
Here is a trivial example of when this might be useful. This
little procedure lets you create and update Customer records
in a REPEAT loop, and then shows you how many were created:
|
The REPEAT block defines the scope of a transaction. Each
time the AVM runs through the block is a separate transaction and,
as each iteration completes successfully, the record created in
that block is committed to the database. If you run the procedure,
the REPEAT loop lets you enter Customers until
you press ESCAPE, which in an OpenEdge session
running on MS Windows is mapped to the END-ERROR key
label. Each time it goes through the block, the AVM creates a Customer, displays
its new CustNum (assigned by the CREATE trigger
for Customer), and prompts you for a Name.
It is at this point that you can press ESCAPE when
you're done entering Customers. This undoes
and leaves the current iteration of the REPEAT block.
Because each iteration of the REPEAT block is a
separate transaction, the final Customer you
created is undone—it is erased from the database.
But what about the iCount variable? Since this
was defined as undoable (the default), the final change to its value
is rolled back along with everything else, and its value is the
actual number of records created and committed to the database,
as shown in the following figure.
As you enter the REPEAT block for the third
time, the AVM creates a third new Customer and
increments iCount from 2 to 3. When you press ESCAPE, the final iteration of the REPEAT block is undone, and Customer 8620 is
deleted from the database. The value of iCount is restored to
2, which was its value before that iteration of the block. (Note that the key value 8620
cannot be undone or reused, however, because it comes from a database sequence, and for
performance reasons, these are not under transaction control).
If the variable were defined NO-UNDO, then after
it is incremented from 2 to 3 its value would not be restored when
the final transaction is undone, and the final DISPLAY statement
would show its value as 3.
NO-UNDO.
(The OpenEdge editor macros do this for you when you type DVI, DVC, etc. into the Editor.) So
why is not NO-UNDO the default? Quite simply, it did not at
first occur to the developers of the language that most variables should be defined this way,
so the first versions of ABL went out with undo variables as the default. Because of the
commitment to maintaining the behavior of existing applications, the default has not changed
with new releases. VAR statement instead of DEFINE VARIABLE, which has
NO-UNDO behavior by default.The same consideration applies to temp-tables. Because temp-tables
are really database tables that are not stored in a persistent database,
they have almost all of the capabilities of true database tables,
including the ability to be written to disk temporarily, the ability
to have indexes, and the ability to participate in transactions.
As with variables, your temp-tables are more efficient if you define
them as NO-UNDO so that they are left out of transactions.
Consider whenever you define a temp-table whether it really needs to
be part of your transactions. If not, include the NO-UNDO keyword
in its definition.