public static class TransactionManager.TransactionHelper
extends java.lang.Object
Modifier and Type | Field and Description |
---|---|
ErrorManager.ErrorHelper |
errHlp
Quick access to context-local error helper.
|
private TransactionManager.WorkArea |
wa
The
TransactionManager.WorkArea instance. |
Constructor and Description |
---|
TransactionHelper(TransactionManager.WorkArea wa)
Create a new instance and associate the given WorkArea instance.
|
Modifier and Type | Method and Description |
---|---|
boolean |
_isRetry()
Reports if the current iteration of this block or loop is a retry.
|
void |
abnormalEnd(java.lang.Throwable thr)
Notifies the transaction manager that an unexpected exception or error
has occurred and that any transaction must be aborted.
|
void |
abnormalEnd(java.lang.Throwable thr,
boolean needsNotify)
Notifies the transaction manager that an unexpected exception or error
has occurred and that any transaction must be aborted.
|
void |
abortProcessing()
Method called when the processing needs to be terminated.
|
void |
batchStart()
Notify all registered
BatchListener objects that a batch is
starting. |
void |
batchStop()
Notify all registered
BatchListener objects that a batch is
stopping. |
(package private) void |
beginTx()
Begin an explicit transaction, at the
root FWD block . |
boolean |
blockInitialized()
Check if the latest block has initialized.
|
void |
blockSetup()
Provides a callback entry point for the top of the loop.
|
void |
checkTransaction(java.lang.String db)
Check whether the transaction id should be set for a database.
|
void |
cleanupPending()
Allow finalizables to do their cleanup (
Finalizable.initFailure() ) now since the
scoped they were designed was aborted and there won't be other chance to call their
Finalizable.finished() . |
(package private) void |
commitTx(boolean chained)
Commit the transaction, at the
root FWD block . |
Stack<BlockDefinition> |
copyStack()
Used to make a weak block stack snapshot.
|
int |
currentOperation()
Reports on the current
Finalizable operation being
executed. |
int |
currentTransactionLevel()
Reports the transaction level of the current block.
|
void |
deferError(java.lang.String action,
java.lang.Throwable thr)
Defer handling of an exception thrown by a commit/rollback notification
callback on a registered
Commitable , so that iteration or pop
scope processing can be continued without interruption. |
void |
deferError(java.lang.String action,
java.lang.Throwable thr,
boolean silent)
Defer handling of an exception thrown by a commit/rollback notification
callback on a registered
Commitable , so that iteration or pop
scope processing can be continued without interruption. |
void |
deregisterGlobalFinalizable(Finalizable target)
Remove the given finalizable from the global list of finalizables.
|
(package private) OutputParameterAssigner |
deregisterOutputParameterAssigner()
Deregister the output parameter assigner for the current block, if any.
|
(package private) void |
endTx()
End an explicit transaction, at the
root FWD block . |
int |
findNearestExternal()
Search the stack of scopes and return the level of the first external
block found.
|
int |
findNearestTopLevel()
Search the stack of scopes and return the level of the first top level
block found.
|
void |
forceRetry()
Force a retry of the current block (if there is no pending rollback)
or retry the same block as the pending rollback, in either case
ensure that the flow of control will not naturally continue.
|
void |
forceRetry(java.lang.String label)
Force a retry of the current block or the scope named by the given
label, ensuring that the flow of control will not naturally continue.
|
(package private) BlockDefinition |
getBlock(int levels)
Get the executing block at the specified level.
|
BlockType |
getBlockType()
Returns the current block type.
|
int |
getFullTransactionBlock()
Returns the index of the full transaction block, or -1 if none exists.
|
int |
getInteractions()
Gets the number of interactive language statements (statements which
took user input except for PAUSE) that have executed in the current
block since the most recent start scope, iterate or retry.
|
BlockType |
getNearestTopLevelType()
Search the stack of scopes and return the type of first top level block found.
|
int |
getNestingLevel()
Returns the current nesting level.
|
java.util.Set<QueryOffEndListener> |
getOffEndListeners(boolean clear)
Get the topmost set of off-end
listeners . |
void |
hadPause()
Notifies this class that an interactive pause has occurred.
|
boolean |
hadRollback()
Reports whether the current block was just rolled back or a containing
block has a pending rollback.
|
boolean |
hasEndkeyProp()
Reports if the current block has the ENDKEY property.
|
boolean |
hasErrorProp()
Reports if the current block has the ERROR property.
|
boolean |
hasParentIteratedBlock()
This checks if any of the enclosing loops has iterated at least once.
|
boolean |
hasQuitProp()
Reports if the current block has the QUIT property.
|
boolean |
hasStopProp()
Reports if the current block has the STOP property.
|
void |
honorError(ErrorConditionException err)
Check if the current error must unwind all the way to the caller of
the top-level block in this method (if the ignore flag is set).
|
boolean |
honorNext(java.lang.String label)
Determines if a NEXT operation with the given target block should
be honored or if the NEXT should be converted to a LEAVE.
|
void |
honorRetry(RetryUnwindException rue)
Check if there is a pending retry of the current block and if so then
enable retry.
|
void |
honorStop(StopConditionException exc)
Dispatch the given exception to all registered stop condition handlers
to see if any requires that the STOP condition be vetoed at the
current scope.
|
void |
honorStopCondition()
Tests the interrupted status of the current thread using
Thread.interrupted , if true then a
StopConditionException will be thrown. |
void |
incrementInteractions()
Increases the number (by 1) of interactive language statements
(statements which took user input except for PAUSE) that have executed
in the current block since the most recent start scope, iterate or
retry.
|
boolean |
isBreakPending()
Accesses the state of whether there is a pending break that must be
honored.
|
boolean |
isEnclosingRollup()
Get the rollup value for the enclosing block.
|
boolean |
isExternalBlock()
Reports if the current block is a external block (this corresponds
with a method-level block that was derived from a Progress external
procedure).
|
boolean |
isFullTransaction()
Reports if the current scope defines the outermost transaction block
(which is the scope at which final commit processing must occur).
|
boolean |
isGlobalBlock()
Reports if the current block is a global scoped block.
|
boolean |
isHeadless()
Report if this context should be treated as headless.
|
boolean |
isNestedMode()
Reports on the enable/disable state of nested error mode.
|
boolean |
isOffEndListener(QueryOffEndListener listener)
Check if the given listener is registered for query off-end events and
can override the default END-KEY action (which is UNDO, LEAVE), when
the current block is FOR or FOR EACH.
|
boolean |
isProcessingQuit()
During global finish processing, this reports if the exit was caused
by a
QuitConditionException . |
boolean |
isRemote()
Check if this session is an appserver session or not.
|
logical |
isRetry()
Reports if the current iteration of this block or loop is a retry.
|
boolean |
isRollup()
Get the rollup value for the current block.
|
boolean |
isRootNestingLevel()
Check if this is block is the block associated with the root external program,
in the 4GL legacy stack.
|
boolean |
isSuppressError()
Check if this block's caller requires errors to be suppressed.
|
boolean |
isTopLevelBlock()
Reports if the current block is a top-level block (this corresponds
with a method-level block).
|
boolean |
isTopLevelDatabaseTrigger()
Detect if the top-most block is a database trigger
|
boolean |
isTransaction()
Reports if there is a current transaction which is active.
|
logical |
isTransactionActive()
Reports if there is a current transaction which is active.
|
boolean |
isTransactionAt(int blockDepth)
Reports if there is a current active transaction at the specified block depth.
|
void |
makeBackup()
Creates or updates the backup set for all objects needing rollback
support in the current block, if a transaction is active.
|
void |
markEndkeyRetry()
Records the fact that the pending RETRY is being caused by an ENDKEY
condition.
|
(package private) BlockDefinition |
nearestExecutingBlock()
Get the BlockDefinition instance of the nearest block of one of the
following types:
external procedure
internal procedure
user-defined function
trigger
trigger
editing
|
boolean |
needsRetry()
Determines if the currently executing block should be retried.
|
void |
notifyCondition(BlockManager.Condition condition)
Notify
ConditionListener instances about condition. |
void |
notifyCondition(ConditionException condition)
Notify
ConditionListener instances about exception condition. |
void |
popScope()
Remove the current block from the stack of scopes, process any pending
rollbacks (if the current block is the proper target), notify any
objects needing commits (if the block finished successfully) and handle
finish processing for the block.
|
void |
processOffEndListeners(boolean init)
Iterate all registered off-end listeners and call the
initialize or
finish method, depending on the
flag. |
(package private) void |
processValidate()
Worker that notifies all objects in the commit list that they must
commit (persist any state).
|
void |
pushScope(java.lang.String label,
int level,
boolean external,
boolean topLevel,
boolean loop,
boolean next)
Initializes a new scope, the associated block definition data
structures.
|
void |
pushScope(java.lang.String label,
int level,
boolean external,
boolean topLevel,
boolean loop,
boolean next,
Block block)
Initializes a new scope, the associated block definition data
structures.
|
void |
pushScope(java.lang.String label,
int level,
boolean external,
boolean topLevel,
boolean loop,
boolean next,
BlockType blockType,
Block block)
Initializes a new scope, the associated block definition data
structures.
|
void |
pushScope(java.lang.String label,
int level,
int props,
boolean external,
boolean topLevel,
boolean loop,
boolean next,
BlockType blockType,
Block block)
Initializes a new scope, the associated block definition data
structures.
|
void |
pushScope(java.lang.String label,
int level,
int props,
boolean external,
boolean topLevel,
boolean loop,
boolean next,
boolean databaseTrigger,
BlockType blockType,
Block block)
Initializes a new scope, the associated block definition data
structures.
|
(package private) void |
registerAt(int transLevel,
boolean persistent,
LazyUndoable... undoTargets)
Adds the object into a scoped dictionary of objects requiring UNDO support.
|
(package private) void |
registerAt(ScopeLevel scope,
LazyUndoable... target)
Adds the given object into the list of objects which require undo
notifications for the next block that is opened.
|
void |
registerBatchListener(BatchListener target)
Adds the given object into the batch notifier list.
|
void |
registerCommit(Commitable target)
Adds the given object into the list of objects for the current block
which require commit notification.
|
void |
registerCommitAt(int blockDepth,
Commitable target)
Adds the given object into the list of objects which require commit notification for the
block at the specified depth This form of registration is useful for objects whose natural
lifetime are scoped to a different block than the block in which they must be committed.
|
void |
registerCurrent(LazyUndoable... undoTargets)
Register the specified targets as undoables.
|
void |
registerFinalizable(Finalizable target,
boolean global)
Adds the given object into the list of objects for the specified block
which require iterate/retry/finish notification.
|
void |
registerFinalizableAt(int blockDepth,
Finalizable target)
Adds the given object into the list of objects for the specified block
which require iterate/retry/finish notification.
|
void |
registerNearestLoopFinalizable(Finalizable target)
Adds the given object into the list of objects which require
iterate/retry/finish notification for the nearest enclosing, looping
block.
|
(package private) void |
registerNext(LazyUndoable... target)
Adds the given object into the list of objects which require undo
notifications for the next block that is opened.
|
void |
registerNextExternal(Finalizable target)
Adds the given object into the list of objects which require
iterate/retry/finish notifications for the next block that is opened
which is a top-level block that corresponds to a Progress external
procedure.
|
void |
registerOffEndQuery(P2JQuery query)
Register the passed query for query off-end events.
|
void |
registerOutputParameterAssigner(OutputParameterAssigner opa)
Register the single output parameter assigner for the current block.
|
void |
registerResettable(Resettable resettable)
Register the given
Resettable object in order to reset it
at specific points of block processing. |
void |
registerScopeable(Scopeable target)
Adds the given object into the list of global objects needing scope
related notifications upon the entry and exit from every block.
|
void |
registerStopVetoHandler(StopConditionVetoHandler h)
Register the given object as a handler which can veto the processing of
STOP condition processing at the current scope.
|
void |
registerTopLevelFinalizable(Finalizable target,
boolean external)
Adds the given object into the list of objects which require
iterate/retry/finish notifications for the nearest enclosing
top-level block.
|
void |
registerTransactionCommit(Commitable target,
boolean remove)
Adds the given object as the transaction level reference which will get
a single, "master" commit call after all other commits have been
processed at the full transaction level.
|
void |
registerTransactionFinish(Finalizable target,
boolean remove)
Adds the given object as the transaction level reference which will get
a "master" finish call after all other finish notifications have been
processed at the full transaction level.
|
boolean |
removeFinalizable(Finalizable target)
Removes the given object from the list of objects which require
iterate/retry/finish notifications.
|
void |
resetInteractions()
Resets the number of interactive language statements (statements which
took user input except for PAUSE) that have executed in the current
block to 0.
|
void |
rollback()
Trigger a rollback for all registered
Undoable objects
inside the current active transaction at the scope defined by the
current block. |
void |
rollback(java.lang.String label)
Trigger a rollback for all registered
Undoable objects
inside the current active transaction at the scope defined
explicitly by the given label or implicitly if the label is
null . |
void |
rollback(java.lang.String label,
java.lang.Throwable cause)
Trigger a rollback for all registered
Undoable objects
inside the current active transaction at the scope defined
explicitly by the given label or implicitly if the label is
null . |
void |
rollbackTopLevel()
Trigger a rollback for all registered
Undoable objects
inside the current active transaction at the nearest top level scope. |
(package private) void |
rollbackTx(boolean chained)
Rollback the transaction, at the
root FWD block . |
void |
saveNestedError(ConditionException err)
Store the given exception for re-throwing during
honorError(com.goldencode.p2j.util.ErrorConditionException) if
nested error mode is enabled. |
void |
setNestedMode(boolean mode)
Enable/disable nested error mode.
|
void |
setProcessingQuit(boolean quit)
During global finish processing, this sets the flag for an exit that
was caused by a
QuitConditionException . |
void |
setRollup(boolean rollup)
Set the new rollup value for the current block.
|
void |
setupFinallyBlock(java.lang.Runnable fini)
Save the given runnable as the FINALLY block for the next iterate, retry or finished.
|
void |
startOffEndRegistration()
This method is called before the initialization of a FOR or FOR EACH
block.
|
void |
stopOffEndRegistration()
This method is called after the initialization of a FOR or FOR EACH
block is finished.
|
(package private) void |
trackUndoables()
Enable tracking of all the undaobles defined in the next instantiating external program.
|
void |
triggerErrorInCaller()
Force an error to be generated such that it will be caught in the
caller of this method.
|
void |
triggerErrorInCaller(LegacyErrorException lex)
Force an error to be generated such that it will be caught in the
caller of this method.
|
void |
triggerErrorInCaller(java.lang.String text)
Force an error to be generated such that it will be caught in the
caller of this method.
|
void |
triggerRetry()
Force a retry of the current block (if there is no pending rollback)
or the block targeted for a pending rollback.
|
void |
triggerRetry(java.lang.String label)
Force a retry of the current block or the scope named by the given
label.
|
(package private) void |
untrackUndoables(java.lang.Object referent)
Untrack (by removing from all the tx blocks) all the undoables defined and registered for
the specified external program.
|
public final ErrorManager.ErrorHelper errHlp
private final TransactionManager.WorkArea wa
TransactionManager.WorkArea
instance.public TransactionHelper(TransactionManager.WorkArea wa)
wa
- The TransactionManager.WorkArea
instance.public void checkTransaction(java.lang.String db)
db
- the logical name of the database (The getId()
of the Database
).public int currentOperation()
Finalizable
operation being
executed.OP_NONE
OP_ITERATE
OP_RETRY
OP_FINISHED
public void registerCommit(Commitable target)
registerCurrent(com.goldencode.p2j.util.LazyUndoable...)
processing to control the commit points.
This notification will ONLY occur when there is an active transaction.
Notifications occur in LIFO order; thus, commitables which depend upon others being committed first must be registered before the objects upon which they are dependent.
These registrations naturally are removed when the associated scope is removed.
target
- The object reference to be committed on success. This
cannot be null
.public void registerCommitAt(int blockDepth, Commitable target)
registerCurrent(com.goldencode.p2j.util.LazyUndoable...)
processing to
control the commit points.
This notification will ONLY occur when there is an active transaction.
Notifications occur in LIFO order; thus, commitables which depend upon others being committed first must be registered before the objects upon which they are dependent.
These registrations naturally are removed when the associated scope is removed.
blockDepth
- Zero-based depth of the target block, starting from the outermost block.target
- The object reference to be committed on success. This cannot be
null
.public void registerTransactionCommit(Commitable target, boolean remove)
This notification will ONLY occur when there is an active transaction and it only will be called at the exit of the block that corresponds to the full transaction.
If the full transaction block is also an iterating block, this notification will occur for each iteration of the block.
target
- The object reference to be committed on success. This
can be null
if one intends to clear the current
reference.remove
- If true
automatically remove this registration
after the full transaction scope has ended (whether or not
the commit occurs). If false
, this reference
will remain globally until replaced.public void registerStopVetoHandler(StopConditionVetoHandler h)
h
- The stop condition veto handler.public void registerScopeable(Scopeable target)
WARNING: this method should be called before the first call to
pushScope(java.lang.String, int, boolean, boolean, boolean, boolean)
. This is necessary since this list is global and
there is no history of which notifications have been provided. Thus,
if pushScope
has been called before this method, then
the notifications of scope start for any scopes that have already been
added will never be seen by the target AND more importantly the
registered target will receive end scope notifications for those
scopes even though there was no matching start scope notification!
If this method can't be called from the static initializer of this
class, the target must implement a facility that is safe with this
limitation (scopeFinished
being called for scopes that
never had a matching scopeStart
).
These registrations are global and will not be removed.
target
- The object reference to be notified on scope start and end.
This cannot be null
.public void registerResettable(Resettable resettable)
Resettable
object in order to reset it
at specific points of block processing.resettable
- Resettable
to be registered.public void registerFinalizable(Finalizable target, boolean global)
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope
is removed (after the Finalizable.finished()
method is called)
in the case of a non-global scope OR at the moment that the last
scope has been removed in the case of the global scope.
The given object will only be added if it is not already in the list.
Finalizables for a scope are processed in the same order as they were registered.
target
- The object reference to be notified on any exit from the
block specified. This cannot be null
.global
- Specifies the target scope. false
specifies the
current scope, and true
specifies the global
scope.public void deregisterGlobalFinalizable(Finalizable target)
target
- Finalizable to be removed from the global list.public void registerFinalizableAt(int blockDepth, Finalizable target)
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope
is removed (after the Finalizable.finished()
method is called)
in the case of a non-global scope OR at the moment that the last
scope has been removed in the case of the global scope.
The given object will only be added if it is not already in the list.
Finalizables for a scope are processed in the same order as they were registered.
blockDepth
- zero-based depth of target block, starting from the outermost
block. 0
indicates the global block.target
- The object reference to be notified on any exit from the
block specified. This cannot be null
.public void registerNextExternal(Finalizable target)
This form of registration is useful for objects whose natural lifetime is scoped to the top-level block and which need a hook for cleaning up resources or handling other block termination processing. In particular, it is necessary for objects that are constructed during a class' constructor/initializer (before the external procedure block has opened). Such objects cannot simply register since their construction is not actually enclosed by the block.
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope
is removed (after the Finalizable.finished()
method is called).
The given object will only be added if it is not already in the list.
target
- The object reference to be notified on any exit from the
top-level external block. This cannot be null
.java.lang.IllegalStateException
- if the top-level block cannot be identified.public void cleanupPending()
Finalizable.initFailure()
) now since the
scoped they were designed was aborted and there won't be other chance to call their
Finalizable.finished()
.
After iteration the list is deleted.
Also, cleanup all other pending state being collected while the external program was instantiating.
public void registerTopLevelFinalizable(Finalizable target, boolean external)
This form of registration is useful for objects whose natural lifetime is scoped to the top-level block and which need a hook for cleaning up resources or handling other block termination processing.
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope
is removed (after the Finalizable.finished()
method is called).
The given object will only be added if it is not already in the list.
Finalizables for a scope are processed in the same order as they were registered.
target
- The object reference to be notified on any exit from the
top-level block. This cannot be null
.external
- If true
, register with the nearest enclosing
external block (external procedure), otherwise register with
the nearest enclosing top-level block (which may be but is
not guaranteed to be the external block).java.lang.IllegalStateException
- if the top-level block cannot be identified.public void registerNearestLoopFinalizable(Finalizable target)
This form of registration is useful for objects whose natural lifetime is scoped to the nearest enclosing, looping block and which need a hook for cleaning up resources or handling other block termination processing.
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope
is removed (after the Finalizable.finished()
method is called).
The given object will only be added if it is not already in the list.
target
- The object reference to be notified on any exit from or
iteration of the target block. This cannot be
null
.java.lang.IllegalStateException
- if no enclosing, looping block can be identified.public boolean removeFinalizable(Finalizable target)
After this call, no notifications will be received.
target
- The object reference to be removed.true
if the target instance was found and
removed.public void registerTransactionFinish(Finalizable target, boolean remove)
This notification will ONLY occur when there is an active transaction and it only will be called at the exit of the block that corresponds to the full transaction.
Multiple targets may be registered by invoking this method multiple times. However, the same object registered multiple times will receive the notification only once per full transaction block exit. If multple targets are registered, they will be called in the order in which they were registered.
target
- The object reference to be finished at full transaction block
end.remove
- If true
automatically remove this registration
after the full transaction scope has ended. If
false
, this reference will remain globally until
replaced.public void registerBatchListener(BatchListener target)
batchStart()
and batchStop()
. Every object
in the list will be notified in the order in which they were added to
the list.target
- The object reference to be notified of any batch start and
stop.public boolean hadRollback()
true
if there was or will be a rollback.public void rollback()
Undoable
objects
inside the current active transaction at the scope defined by the
current block. All objects that are rolled back will have their
values assigned based on the values backed up at the start of the
specified scope. A flow control change MUST always immediately follow
this method otherwise undefined results can occur.
This caller-driven control flow is required to properly duplicate the semantics of Progress 4GL condition processing which always generates an implicit or explicit flow control action after every UNDO. Since the flow of control change can reference a different scope than that of the rollback, this can't be handled by re-throwing the exception but must instead be separately driven by a deferred rollback and a caller driven flow control statement such as break, continue or return. The key limitation that makes this possible is the fact that the UNDO (rollback) scope MUST ALWAYS BE equivalent to or more specific than the scope to which flow of control will be changed. This means that one can rollback at a more deeply nested scope but change flow of control to resume processing at a different (less deeply nested) scope. The reverse is not possible.
public void rollback(java.lang.String label)
Undoable
objects
inside the current active transaction at the scope defined
explicitly by the given label or implicitly if the label is
null
. All objects that are rolled back will have their
values assigned based on the values backed up at the start of the
specified scope. If the current scope is not the target scope, the
given exception will be stored, the rollback will be deferred and
the rollback will be processed as the scopes naturally unwind. This
unwinding must be generated by a change in flow of control by the
calling code. This flow control change MUST always immediately follow
this method otherwise undefined results can occur.
This caller-driven control flow is required to properly duplicate the semantics of Progress 4GL condition processing which always generates an implicit or explicit flow control action after every UNDO. Since the flow of control change can reference a different scope than that of the rollback, this can't be handled by re-throwing the exception but must instead be separately driven by a deferred rollback and a caller driven flow control statement such as break, continue or return. The key limitation that makes this possible is the fact that the UNDO (rollback) scope MUST ALWAYS BE equivalent to or more specific than the scope to which flow of control will be changed. This means that one can rollback at a more deeply nested scope but change flow of control to resume processing at a different (less deeply nested) scope. The reverse is not possible.
label
- Specifies the name of the scope at which to rollback or
null
if the scope should be implicitly
determined.public void rollback(java.lang.String label, java.lang.Throwable cause)
Undoable
objects
inside the current active transaction at the scope defined
explicitly by the given label or implicitly if the label is
null
. All objects that are rolled back will have their
values assigned based on the values backed up at the start of the
specified scope. If the current scope is not the target scope, the
given exception will be stored, the rollback will be deferred and
the rollback will be processed as the scopes naturally unwind. This
unwinding must be generated by a change in flow of control by the
calling code. This flow control change MUST always immediately follow
this method otherwise undefined results can occur.
This caller-driven control flow is required to properly duplicate the semantics of Progress 4GL condition processing which always generates an implicit or explicit flow control action after every UNDO. Since the flow of control change can reference a different scope than that of the rollback, this can't be handled by re-throwing the exception but must instead be separately driven by a deferred rollback and a caller driven flow control statement such as break, continue or return. The key limitation that makes this possible is the fact that the UNDO (rollback) scope MUST ALWAYS BE equivalent to or more specific than the scope to which flow of control will be changed. This means that one can rollback at a more deeply nested scope but change flow of control to resume processing at a different (less deeply nested) scope. The reverse is not possible.
label
- Specifies the name of the scope at which to rollback or
null
if the scope should be implicitly
determined.cause
- The exceptional cause, if any, of the rollback.public void rollbackTopLevel()
Undoable
objects
inside the current active transaction at the nearest top level scope.
All objects that are rolled back will have their values assigned based
on the values backed up at the start of the specified scope. If the
current scope is not the target scope, the given exception will be
stored, the rollback will be deferred and the rollback will be processed
as the scopes naturally unwind. This unwinding must be generated by a
change in flow of control by the calling code. This flow control change
MUST always immediately follow this method otherwise undefined results
can occur.
This caller-driven control flow is required to properly duplicate the semantics of Progress 4GL condition processing which always generates an implicit or explicit flow control action after every UNDO. Since the flow of control change can reference a different scope than that of the rollback, this can't be handled by re-throwing the exception but must instead be separately driven by a deferred rollback and a caller driven flow control statement such as break, continue or return. The key limitation that makes this possible is the fact that the UNDO (rollback) scope MUST ALWAYS BE equivalent to or more specific than the scope to which flow of control will be changed. This means that one can rollback at a more deeply nested scope but change flow of control to resume processing at a different (less deeply nested) scope. The reverse is not possible.
public void pushScope(java.lang.String label, int level, boolean external, boolean topLevel, boolean loop, boolean next)
blockSetup()
and
makeBackup()
).
In the case of a block which is defined as NO_TRANSACTION
,
the core data structures are initialized but no rollback support will
be provided.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
.
This will create a block of BlockType.UNKNOWN
and block
properties PROP_NONE
.
label
- The text label associated with the block. This usually
should correspond with the label used in the source file
to identify the block for purposes of the break and continue
statements.level
- One of TransactionManager.NO_TRANSACTION
, TransactionManager.SUB_TRANSACTION
or
TransactionManager.TRANSACTION
. This code defines the level of
rollback and transaction support which should be provided.external
- true
if this block is associated with the
external procedure (in Progress terms). This controls the
cleanup of certain resources such as temp-tables, frames
and streams.topLevel
- true
if this block is a method.loop
- Defines if this block is a loop or not.next
- true
if this infinite loop protection should
convert a retry into a next (continue), otherwise the retry
will be converted into a leave (break).StopConditionException
- If the current thread's was previously interrupted.public void pushScope(java.lang.String label, int level, boolean external, boolean topLevel, boolean loop, boolean next, Block block)
blockSetup()
and
makeBackup()
).
In the case of a block which is defined as NO_TRANSACTION
,
the core data structures are initialized but no rollback support will
be provided.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
.
This will create a block of BlockType.UNKNOWN
and block
properties PROP_NONE
.
label
- The text label associated with the block. This usually
should correspond with the label used in the source file
to identify the block for purposes of the break and continue
statements.level
- One of TransactionManager.NO_TRANSACTION
, TransactionManager.SUB_TRANSACTION
or
TransactionManager.TRANSACTION
. This code defines the level of
rollback and transaction support which should be provided.external
- true
if this block is associated with the
external procedure (in Progress terms). This controls the
cleanup of certain resources such as temp-tables, frames
and streams.topLevel
- true
if this block is a method.loop
- Defines if this block is a loop or not.next
- true
if this infinite loop protection should
convert a retry into a next (continue), otherwise the retry
will be converted into a leave (break).block
- The Block instance to be executed. May be null, if no Block
instance is needed (i.e. this is an internal P2J call).StopConditionException
- If the current thread's was previously interrupted.public void pushScope(java.lang.String label, int level, boolean external, boolean topLevel, boolean loop, boolean next, BlockType blockType, Block block)
blockSetup()
and
makeBackup()
).
In the case of a block which is defined as NO_TRANSACTION
,
the core data structures are initialized but no rollback support will
be provided.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
.
This will create a block with block properties PROP_NONE
.
label
- The text label associated with the block. This usually
should correspond with the label used in the source file
to identify the block for purposes of the break and continue
statements.level
- One of TransactionManager.NO_TRANSACTION
, TransactionManager.SUB_TRANSACTION
or
TransactionManager.TRANSACTION
. This code defines the level of
rollback and transaction support which should be provided.external
- true
if this block is associated with the
external procedure (in Progress terms). This controls the
cleanup of certain resources such as temp-tables, frames
and streams.topLevel
- true
if this block is a method.loop
- Defines if this block is a loop or not.next
- true
if this infinite loop protection should
convert a retry into a next (continue), otherwise the retry
will be converted into a leave (break).blockType
- Specifies this block's type.block
- The Block instance to be executed.StopConditionException
- If the current thread's was previously interrupted.public void pushScope(java.lang.String label, int level, int props, boolean external, boolean topLevel, boolean loop, boolean next, BlockType blockType, Block block)
blockSetup()
and
makeBackup()
).
In the case of a block which is defined as NO_TRANSACTION
,
the core data structures are initialized but no rollback support will
be provided.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
label
- The text label associated with the block. This usually
should correspond with the label used in the source file
to identify the block for purposes of the break and continue
statements.level
- One of TransactionManager.NO_TRANSACTION
, TransactionManager.SUB_TRANSACTION
or
TransactionManager.TRANSACTION
. This code defines the level of
rollback and transaction support which should be provided.props
- A bitfield storing block properties which will be a
combination of TransactionManager.PROP_NONE
, TransactionManager.PROP_ERROR
,
TransactionManager.PROP_ENDKEY
, TransactionManager.PROP_STOP
or
TransactionManager.PROP_QUIT
.external
- true
if this block is associated with the
external procedure (in Progress terms). This controls the
cleanup of certain resources such as temp-tables, frames
and streams.topLevel
- true
if this block is a method.loop
- Defines if this block is a loop or not.next
- true
if this infinite loop protection should
convert a retry into a next (continue), otherwise the retry
will be converted into a leave (break).blockType
- Specifies this block's type.block
- The Block instance to be executed.StopConditionException
- If the current thread's was previously interrupted.public void pushScope(java.lang.String label, int level, int props, boolean external, boolean topLevel, boolean loop, boolean next, boolean databaseTrigger, BlockType blockType, Block block)
blockSetup()
and
makeBackup()
).
In the case of a block which is defined as NO_TRANSACTION
,
the core data structures are initialized but no rollback support will
be provided.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
label
- The text label associated with the block. This usually
should correspond with the label used in the source file
to identify the block for purposes of the break and continue
statements.level
- One of TransactionManager.NO_TRANSACTION
, TransactionManager.SUB_TRANSACTION
or
TransactionManager.TRANSACTION
. This code defines the level of
rollback and transaction support which should be provided.props
- A bitfield storing block properties which will be a
combination of TransactionManager.PROP_NONE
, TransactionManager.PROP_ERROR
,
TransactionManager.PROP_ENDKEY
, TransactionManager.PROP_STOP
or
TransactionManager.PROP_QUIT
.external
- true
if this block is associated with the
external procedure (in Progress terms). This controls the
cleanup of certain resources such as temp-tables, frames
and streams.topLevel
- true
if this block is a method.loop
- Defines if this block is a loop or not.next
- true
if this infinite loop protection should
convert a retry into a next (continue), otherwise the retry
will be converted into a leave (break).databaseTrigger
- true
if this scope should create a definition
of a database trigger block.blockType
- Specifies this block's type.block
- The Block instance to be executed.StopConditionException
- If the current thread's was previously interrupted.public void popScope() throws StopConditionException
finally
block such that this is guaranteed to be called
no matter how the flow of control exits the associated block (exception,
break, return or the flow of control naturally passing through the
end of the block).
Rollback and commit processing only occur when there is an active transaction. Otherwise this processing is bypassed. Finish processing is always called.
This method implements global finish processing (as the last action before returning) when the last scope is popped from the stack of scopes. For this reason, the current implementation assumes that the session is over at the moment that the top-most user-defined scope exits.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
StopConditionException
- If the current thread's was previously interrupted.public void notifyCondition(BlockManager.Condition condition)
ConditionListener
instances about condition.condition
- The condition the listeners will be notified.public void notifyCondition(ConditionException condition)
ConditionListener
instances about exception condition.condition
- The instance of ConditionException
.public boolean blockInitialized()
public void blockSetup() throws StopConditionException
makeBackup()
. On the second and subsequent executions of this
method for a given block, this method handles iterate
notifications.
It is important to note that continue
can be called from
nested blocks at arbitrary depths. This method can handle such nesting
at any level.
This method will honor any pending thread interruption by throwing
a StopConditionException
using honorStopCondition()
StopConditionException
- If the current thread's was previously interrupted.public void setupFinallyBlock(java.lang.Runnable fini)
fini
- The FINALLY block code to execute.public void makeBackup()
pushScope(java.lang.String, int, boolean, boolean, boolean, boolean)
and blockSetup()
due to the
semantics of Progress in which the backup set is created or refreshed
after the loop control variables have been modified.public logical isTransactionActive()
true
if a transaction is active.public boolean _isRetry()
true
if this is a retry of this block or loop
(as opposed to the first time through this iteration).public logical isRetry()
true
if this is a retry of this block or loop
(as opposed to the first time through this iteration).public void markEndkeyRetry()
public boolean hasParentIteratedBlock()
true
if any of the enclosing loops has iterated
at least once.public boolean honorNext(java.lang.String label)
A NEXT is converted into a LEAVE when all of the following conditions are true:
Since NEXT is only possible on a looping block, if the target block
is not a looping block then this method will return false
.
label
- The label of the target block for the NEXT action.true
for NEXT, false
for LEAVE.public boolean needsRetry()
true
if the block (whether or not it is a loop)
should be retried.public boolean isBreakPending()
true
if a break is pending for this block.public void triggerErrorInCaller(java.lang.String text) throws ErrorConditionException
honorError(com.goldencode.p2j.util.ErrorConditionException)
.
In the case where silent error mode is enabled in the calling method,
the "normal" stack unwinding approach cannot be used because the
exception cannot be thrown. Instead, the error manager will be updated
with the error data and this method will silently return. It is
critical that in such cases the calling code must immediately execute a
return
statement which will maintain the proper Progress
behavior. The caller can check the error manager to determine that an
error occurred.
Detecting the silent error mode in the caller requires that the top level block be found. The silent error flag of the caller is cached there.
text
- The text to use as the error message in the exception.ErrorConditionException
public boolean isSuppressError()
public void triggerErrorInCaller() throws ErrorConditionException
honorError(com.goldencode.p2j.util.ErrorConditionException)
.
In the case where silent error mode is enabled in the calling method,
the "normal" stack unwinding approach cannot be used because the
exception cannot be thrown. Instead, the error manager will be updated
with the error data and this method will silently return. It is
critical that in such cases the calling code must immediately execute a
return
statement which will maintain the proper Progress
behavior. The caller can check the error manager to determine that an
error occurred.
Detecting the silent error mode in the caller requires that the top level block be found. The silent error flag of the caller is cached there.
ErrorConditionException
public void triggerErrorInCaller(LegacyErrorException lex) throws ErrorConditionException
honorError(com.goldencode.p2j.util.ErrorConditionException)
.
In the case where silent error mode is enabled in the calling method,
the "normal" stack unwinding approach cannot be used because the
exception cannot be thrown. Instead, the error manager will be updated
with the error data and this method will silently return. It is
critical that in such cases the calling code must immediately execute a
return
statement which will maintain the proper Progress
behavior. The caller can check the error manager to determine that an
error occurred.
Detecting the silent error mode in the caller requires that the top level block be found. The silent error flag of the caller is cached there.
lex
- The legacy OO-like error to throw.ErrorConditionException
public void forceRetry() throws RetryUnwindException
A RetryUnwindException
will be thrown to unwind the stack
to the given scope, even if the scope is the current block. This
unwinding is dependent upon catch blocks being implemented with a
corresponding call to honorRetry(com.goldencode.p2j.util.RetryUnwindException)
.
This method will NEVER naturally return since an exception is ALWAYS
thrown. This method should generally not be called from within a
catch block if the intention is to retry the current block since it
would be outside of the block's associated try
. In that
case, only an enclosing block could be retried.
RetryUnwindException
- This method always generates this exception to ensure that
natural processing will not continue.public void forceRetry(java.lang.String label) throws RetryUnwindException
RetryUnwindException
will be thrown to unwind the stack
to the given scope, even if the scope is the current block. This
unwinding is dependent upon catch blocks being implemented with a
corresponding call to honorRetry(com.goldencode.p2j.util.RetryUnwindException)
.
This method will NEVER naturally return since an exception is ALWAYS
thrown. This method should generally not be called from within a
catch block if the intention is to retry the current block since it
would be outside of the block's associated try
. In that
case, only an enclosing block could be retried.
label
- The name of the scope to retry. Specify null
to
retry the scope that has a pending rollback OR to retry
the current scope if there is no pending rollback.RetryUnwindException
- This method always generates this exception to ensure that
natural processing will not continue.public void triggerRetry() throws RetryUnwindException
RetryUnwindException
will be
thrown to unwind the stack to the given scope. This unwinding is
dependent upon catch blocks being implemented with a corresponding call
to honorRetry(com.goldencode.p2j.util.RetryUnwindException)
.
If the current block is not the target, the retry is deferred by
marking the target block and then unwinding the stack. Otherwise,
this method will return naturally. This method is only appropriate
to be called from within catch
blocks since a natural
return within a catch
block will fall through to allow
the retry loop to engage.
RetryUnwindException
public void triggerRetry(java.lang.String label) throws RetryUnwindException
RetryUnwindException
will be thrown to unwind the stack
to the given scope. This unwinding is dependent upon catch blocks
being implemented with a corresponding call to honorRetry(com.goldencode.p2j.util.RetryUnwindException)
.
If the current block is not the target, the retry is deferred by
marking the target block and then unwinding the stack. Otherwise,
this method will return naturally. This method is only appropriate
to be called from within catch
blocks since a natural
return within a catch
block will fall through to allow
the retry loop to engage.
label
- The name of the scope to retry. Specify null
to
retry the scope of that has a pending rollback OR to retry
the current scope if there is no pending rollback.RetryUnwindException
public void honorStop(StopConditionException exc) throws StopConditionException
exc
- The exception to be checked.StopConditionException
- if the STOP condition is not honored at this scope.public void honorRetry(RetryUnwindException rue) throws RetryUnwindException
RetryUnwindException
. This unwinding is dependent upon catch
blocks being implemented to call this method.
If the current block is not the target for the pending retry, the exception is re-thrown.
rue
- The exception to honor or ignore.RetryUnwindException
public void honorError(ErrorConditionException err) throws ErrorConditionException
false
then this method returns silently.
This code also honors any nested error that was generated while another error was being processed AND while nested error mode was enabled. Any such stored error will be re-thrown here.
err
- The exception to honor or ignore.ErrorConditionException
public void abnormalEnd(java.lang.Throwable thr) throws java.lang.RuntimeException
Throwable
will be re-thrown as a
RuntimeException
.
If the exception is of type ConditionException
or
RetryUnwindException
, this method will do nothing since
these are used for normal flow of control purposes and are used in
close coordination with the transaction manager's state. They need
no other special behavior to be safe. This method is designed to
handle exceptions (like NullPointerException
) which are
not valid in a converted 4GL program.
thr
- The unexpected exception or error.java.lang.RuntimeException
public void abnormalEnd(java.lang.Throwable thr, boolean needsNotify) throws java.lang.RuntimeException
Throwable
will be re-thrown as a
RuntimeException
.
If the exception is of type ConditionException
or
RetryUnwindException
, this method will do nothing since
these are used for normal flow of control purposes and are used in
close coordination with the transaction manager's state. They need
no other special behavior to be safe. This method is designed to
handle exceptions (like NullPointerException
) which are
not valid in a converted 4GL program.
thr
- The unexpected exception or error.needsNotify
- true
if condition notification must be executed
(only happens if the thr
is a condition).java.lang.RuntimeException
public int currentTransactionLevel()
public boolean isFullTransaction()
true
if the current scope defines the top-level
transaction.public boolean isTransaction()
true
if a transaction is active.public boolean isTransactionAt(int blockDepth)
blockDepth
- Zero-based block depth starting from the outermost block at which transaction
status is checked.true
if a transaction is active at the specified block depth.public boolean isTopLevelBlock()
true
if top-level block, else false
.public boolean isExternalBlock()
false
for blocks derived from
internal procedures, functions and triggers.true
if it is an external block, else
false
.public boolean isGlobalBlock()
true
if the current block is the only block on the stack of block scopes; for
appserver agent contexts: true
if the current block is one of two outermost
blocks ("appserver-agent" and "startup") on the stack of block scopes.public boolean isRemote()
TransactionManager.WorkArea.remote
state.public boolean hasErrorProp()
true
if the current block has the
PROP_ERROR
bit set in its properties bitmap.public boolean hasEndkeyProp()
true
if the current block has the
PROP_ENDKEY
bit set in its properties bitmap.public boolean hasStopProp()
true
if the current block has the
PROP_STOP
bit set in its properties bitmap.public boolean hasQuitProp()
true
if the current block has the
PROP_QUIT
bit set in its properties bitmap.public boolean isProcessingQuit()
QuitConditionException
.true
if this exit is due to a quit condition.public void setProcessingQuit(boolean quit)
QuitConditionException
.quit
- true
if this exit is due to a quit condition.public boolean isHeadless()
true
if this session is headless.public void incrementInteractions()
public void resetInteractions()
public int getInteractions()
public boolean isRollup()
true
,
then any contained blocks that exit will cause the current (containing)
block's interactions counter to be increased by the contained block's
interactions counter. Otherwise, no aggregation will occur.public boolean isEnclosingRollup()
true
,
then the current block's exit will cause the enclosing (containing)
block's interactions counter to be increased by the current block's
interactions counter. Otherwise, no aggregation will occur.public void setRollup(boolean rollup)
true
,
then any contained blocks that exit will cause the current (containing)
block's interactions counter to be increased by the contained block's
interactions counter. Otherwise, no aggregation will occur.rollup
- The new rollup value.public void batchStart()
BatchListener
objects that a batch is
starting.public void batchStop()
BatchListener
objects that a batch is
stopping.public void honorStopCondition() throws StopConditionException, SilentUnwindException
Thread.interrupted
, if true
then a
StopConditionException
will be thrown. The interrupted status
will be true
if a call to Thread.interrupt
was previously made.
The thread's interrupted status is cleared by this method before the
StopConditionException
is thrown.
StopConditionException
- If the current thread's was previously interrupted.SilentUnwindException
- If the connection ended prematurely end the current thread
needs to stop.public void abortProcessing()
error
, on the next honorStopCondition()
call.public void setNestedMode(boolean mode)
honorError(com.goldencode.p2j.util.ErrorConditionException)
this can be re-thrown. This duplicates some
obscure behavior seen in Progress.mode
- true
to enable, false
to disable.public boolean isNestedMode()
honorError(com.goldencode.p2j.util.ErrorConditionException)
this can be
re-thrown.true
if nested error mode is enabled.public BlockType getBlockType()
public int getFullTransactionBlock()
public int getNestingLevel()
public boolean isRootNestingLevel()
public void saveNestedError(ConditionException err)
honorError(com.goldencode.p2j.util.ErrorConditionException)
if
nested error mode is enabled. Note that only 1 error can ever be nested
and the last one set via this method will be the one that is honored.err
- The error to store.public void hadPause()
public int findNearestExternal()
public void startOffEndRegistration()
TransactionManager.WorkArea.offEndQueries
set and will
set the TransactionManager.WorkArea.offEndRegistration
flag to ON. While this flag
is ON, all created queries will be collected in the
TransactionManager.WorkArea.offEndQueries
set.
After the block initialization is finished, the
stopOffEndRegistration()
will be called.
public void stopOffEndRegistration()
QueryOffEndListener
s
associated with the registered queries
.public void registerOffEndQuery(P2JQuery query)
These queries will be able to end the loop when the last record is reached, by overriding any user-defined END-KEY action. The action wich is executed is the default UNDO, LEAVE action for END-KEY.
query
- The query which needs to be registered.public boolean isOffEndListener(QueryOffEndListener listener)
listener
- A listener to be checked if is registered for off-end events.true
if the listener is registered for query
off-end event.public void processOffEndListeners(boolean init)
initialize
or
finish
method, depending on the
flag.init
- true
if the listeners are initialized; else, the
QueryOffEndListener.finish()
method is called.public java.util.Set<QueryOffEndListener> getOffEndListeners(boolean clear)
listeners
.clear
- true
if the top-most off-end listeners set
should be cleared.public void registerOutputParameterAssigner(OutputParameterAssigner opa)
BlockManager
when it is
time to process assign-backs from function/procedure output parameters
to the database record fields with which they are associated.opa
- An output parameter assigner.java.lang.IllegalStateException
- if a second output parameter assigner is registered for a block
before the current one is deregistered. There can be only one.public void deferError(java.lang.String action, java.lang.Throwable thr)
Commitable
, so that iteration or pop
scope processing can be continued without interruption. This ensures
that all Commitable
s registered after the errant one still
receive their commit/rollback notifications, and that (in the case of
popping a scope), registered Scopeable
s still receive their
scope finished notifications.
If no error is already pending, exc
is stored, to be thrown
upon conclusion of processing the current block scope or iteration. If
an error is already pending, exc
is discarded. In either
case, exc
is logged if error-level logging is enabled.
action
- A brief description of the action occurring at the time the
error was encountered, such as "commit" or "master rollback".thr
- The error caught during processing of a commit or rollback
notification.TransactionManager.WorkArea.handleDeferredError()
public void deferError(java.lang.String action, java.lang.Throwable thr, boolean silent)
Commitable
, so that iteration or pop
scope processing can be continued without interruption. This ensures
that all Commitable
s registered after the errant one still
receive their commit/rollback notifications, and that (in the case of
popping a scope), registered Scopeable
s still receive their
scope finished notifications.
If no error is already pending, exc
is stored, to be thrown
upon conclusion of processing the current block scope or iteration. If
an error is already pending, exc
is discarded. In either
case, exc
is logged if error-level logging is enabled.
action
- A brief description of the action occurring at the time the
error was encountered, such as "commit" or "master rollback".thr
- The error caught during processing of a commit or rollback
notification.silent
- If true
then exception is not logged.TransactionManager.WorkArea.handleDeferredError()
public int findNearestTopLevel()
public BlockType getNearestTopLevelType()
BlockType.UNKNOWN
if
there is no block marked as a top level block.void processValidate() throws ErrorConditionException
On the last iteration of a loop or block which ends in success (in
which the flow of control reaches the natural end of the block), both
will be called in succession. However, other forms of exit which are
still considered successful (i.e. return and break which are not the
result of condition processing) will only execute popScope
and iterate
will be bypassed.
It is important to note that the list of commitables in blk is
iterated in reverse order from that in which they are registered with
the TransactionManager
. This is done to ensure that
database transactions (which are registered before their corresponding
buffers) are always committed after all buffers are committed.
ErrorConditionException
- If validation fails.BlockDefinition nearestExecutingBlock()
BlockDefinition getBlock(int levels)
levels
- Zero-based depth of the target block, starting from the innermost block.null
if the index is outside of the block depth.OutputParameterAssigner deregisterOutputParameterAssigner()
BlockManager
will invoke this
method.null
if none was registered.void registerNext(LazyUndoable... target)
This form of registration is useful for objects whose natural lifetime is scoped to the top-level block. In particular, it is necessary for objects that are constructed during a class' constructor/initializer (before the external procedure block has opened). Such objects cannot simply register since their construction is not actually enclosed by the block.
When the deferred registration occurs, it will NOT be global and will NOT be added to registered Commitables.
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope is removed.
The given object will only be added if it is not already in the list.
target
- The object references to be registered. This cannot be
null
.void registerAt(ScopeLevel scope, LazyUndoable... target)
This form of registration is useful for objects whose natural lifetime is scoped to the top-level block. In particular, it is necessary for objects that are constructed during a class' constructor/initializer (before the external procedure block has opened). Such objects cannot simply register since their construction is not actually enclosed by the block.
When the deferred registration occurs, it will NOT be global and will NOT be added to registered Commitables.
This notification will occur whether or not a transaction is active.
These registrations naturally are removed when the associated scope is removed.
The given object will only be added if it is not already in the list.
scope
- The scope where to register the undoable targets.target
- The object references to be registered. This cannot be
null
.public void registerCurrent(LazyUndoable... undoTargets)
undoTargets
- List of object references to be registered. This cannot be
null
.void registerAt(int transLevel, boolean persistent, LazyUndoable... undoTargets)
These registrations naturally are removed when the associated scope is removed. However, the global scope is long-lived. Special care is necessary to prevent the same instance of global shared variables being added multiple times.
transLevel
- The transaction level to set for this undoable.persistent
- Flag indicating if the undoable is defined in a persistent procedureundoTargets
- The object references to be rolled back on failure. This
cannot be null
.void trackUndoables()
void untrackUndoables(java.lang.Object referent)
referent
- The external program instance.void rollbackTx(boolean chained)
root FWD block
.chained
- Flag indicating if a new transaction will be started.void commitTx(boolean chained)
root FWD block
.chained
- Flag indicating if a new transaction will be started.void beginTx()
root FWD block
.
This explicitly marks this tx as being open by the
TRANS-INIT-PROCEDURE
.
void endTx()
root FWD block
.public boolean isTopLevelDatabaseTrigger()
public Stack<BlockDefinition> copyStack()