The AVM undoes a transaction automatically if it detects an error at the database level, for example, because of a unique key violation. In many cases, your application logic also wants to undo a transaction when you detect a violation of your business logic. The UNDO statement lets you control when to cancel the effects of a transaction on your own. It also lets you define just how much of your procedure logic to undo.
In its simplest form, you can use the UNDO keyword as its own statement. In this case, the AVM undoes the innermost containing block with the error property, which can be:
A FOR block
A REPEAT block
A procedure block
A DO block with the TRANSACTION keyword or ON ERROR phrase
You can change this default by specifying a block label to undo. You can place a block name anywhere in your procedure. The block name must adhere to the same rules as a variable name and it must be followed by a colon. If you use this block name in an UNDO statement, it identifies how far back you want the AVM to undo transactional work.
The default action on an UNDO is to attempt to retry the current block. In ABL, a block of code that prompts the user for field values can be retried; that is, having entered invalid data, the user can re-enter different values. If you are writing well-structured procedures that do not mix user interface elements with database logic, then retrying a block never results in a user entering different values. the AVM recognizes this and changes the action to a NEXT of an iterating block, or a LEAVE of a noniterating block, so this is effectively the default for transactions not involving user interface events.
You can change this default action as well. If you specify LEAVE, you can name the block to leave. This defaults to the block you undo.
If you specify NEXT within an iterating block, then after the UNDO the AVM proceeds to the next iteration of either the block whose label you specify or the block you undo as a default. Use the NEXT option if each iteration of a repeating block is its own transaction (the default) and if you want the AVM to keep trying to apply changes to other records, for example, as the AVM walks through a set of records in a FOR EACH block.
If you specify RETRY, then you can retry either the current block (the default) or the same block you applied the UNDO statement to. Again, in a properly structured application, you do not need to use the RETRY option.
Finally, you can RETURN out of the current procedure. You can RETURN ERROR, which raises the the AVM error condition, or you can use RETURN NO-APPLY to cancel the effect of the last user-interface event. Once again, this is not an option you would normally use in server-side business logic. The RETURN option can also specify a return-string, which becomes the RETURN-VALUE in the procedure you return to.
You can also specify UNDO as an option on a DO, FOR, or REPEAT block, as you did in your saveOrder example procedure:
DO TRANSACTION ON ERROR UNDO, LEAVE:
Note: In structured error handling, the UNDO statement or the ON ERROR phrase can pass an error as an object from an inner block to an outer block using the THROW syntax. See OpenEdge Development: Error Handling for complete documentation.