public final class BufferManager extends java.lang.Object implements Scopeable, Commitable, BatchListener, StopConditionVetoHandler, Resettable
TransactionManager
, the
persistence service layer which manages database resources, and multiple
record buffers opened by client code.
A record buffer registers itself with the buffer manager when client code opens a new buffer scope. If a transaction is active, that buffer is immediately registered with the transaction manager for commit processing. This allows the buffer to synchronize its state with the persistence service when a transaction or subtransaction commit occurs. If a transaction is not active when a new buffer scope is opened, the buffer manager keeps track of the open buffer, and the block scope at which it was opened. When a full transaction subsequently is opened, all buffers with open scopes are batch registered for commit processing.
Also, when a full transaction begins, the buffer manager takes stock of
all databases referred to by open buffer scopes, and begins a new,
database-level transaction for each one. The database transaction's life
cycle is managed by an inner class, BufferManager.TxWrapper
.
This inner class registers itself for master commit and finish processing
with the transaction manager, such that it can reflect an application
level commit/rollback back to the underlying database transaction.
Updates made to existing records are tracked for undo purposes by this class. A scoped dictionary of reversible updates by DMO type is managed by the context local instance of this class, for all open buffers in the current client context.
Modifier and Type | Class and Description |
---|---|
private static class |
BufferManager.BatchModeData
Container for batch assign mode information.
|
private class |
BufferManager.PersistentProcScope
Buffer-related data for a certain persistent procedure, surviving after its external
procedure is finished.
|
private class |
BufferManager.TempTableKey
A temp-table key contains the lowercase legacy name of the table and the procedure where it
was created.
|
private class |
BufferManager.TxWrapper
An object which manages the "master"
Commitable and Finalizable events of an
application transaction. |
private static class |
BufferManager.UndoData
Storage mechanism for maps of reversible/undoable actions, keyed by
primary key.
|
Modifier and Type | Field and Description |
---|---|
private java.util.Map<Database,MutableInteger> |
activeDatabases
Counter of in-use buffers for each database.
|
private java.util.Set<Persistence.Context> |
activePersistenceContexts
Active persistence contexts (those which have an open database session)
|
private ScopedDictionary<java.lang.String,RecordBuffer> |
allBuffers
Scoped dictionary in which all defined record buffers are stored.
|
private Finalizable |
batchCleaner
Finalizable which clears batch mode at the appropriate times
|
private java.util.ArrayDeque<BufferManager.BatchModeData> |
batchModeStack
Stack of batch mode data
|
private java.util.Map<TemporaryBuffer,java.util.Map<java.lang.Object,java.util.Set<TemporaryBuffer>>> |
bindingBuffers
Map of bound buffers to there destination, for each procedure.
|
private ScopedDictionary<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> |
byLegacyName
Scoped dictionary in which all defined record buffers are stored.
|
(package private) java.util.Map<BufferType,MutableInteger> |
changeScopes
Map of buffer types to high-water block depths of any change to any record of that type
|
private static java.util.Map<java.lang.Class<?>,java.util.Set<java.lang.reflect.Field>> |
classBufferFields
A cache of buffer-related fields defined in a specific legacy-converted class.
|
private ConnectionManager |
connMgr
Connection manager
|
private static ContextLocal<BufferManager> |
context
Stores context local instances of this class
|
private ScopedDictionary<RecordBuffer,java.lang.Boolean> |
dirtyBuffers
The buffer's touched via a Create, Update or Delete operation, in each scope.
|
private Scopeable |
fieldScopes
Field assigner for function/procedure parameter assign-backs
|
private java.util.Map<Database,BufferManager.TxWrapper> |
inactiveTxWrappers
Transaction wrappers not yet activated
|
private static boolean |
initialized
Flag indicating whether class was initialized, i.e.
|
private ScopedDictionary<RecordBuffer,java.lang.Boolean> |
loadedBuffers
Scoped dictionary which key set contains all buffers into which a new record was loaded (or
the old record was reloaded) into corresponding scopes.
|
private static java.util.logging.Logger |
LOG
Logger
|
private boolean |
nestedQueryError
Does a nested query error condition currently exist?
|
private ScopedList<RecordBuffer> |
openBuffers
Scoped dictionary in which open record buffers are stored
|
private ScopedDictionary<BufferManager.TempTableKey,StaticTempTable> |
openStaticTempTables
Scoped dictionary which contains currently active static temp tables (i.e.
|
private java.util.Map<RecordBuffer,java.lang.Class<?>> |
pendingBufferClasses
The defining class of a pending buffer, used when initializing an OE class and/or external program.
|
private java.util.Set<RecordBuffer> |
pendingBuffers
The buffers which will be registered on the next scope entry.
|
private java.util.Map<Persistence,java.util.Set<java.lang.Long>> |
pendingReclaimedKeys
Primary keys pending reclamation
|
private java.util.Map<StaticTempTable,java.lang.Boolean> |
pendingStaticTempTables
A map of static temp-tables pending registration.
|
private java.util.Map<java.lang.Object,BufferManager.PersistentProcScope> |
persistProcScopes
Map with buffer-related data surviving a persistent proc's external procedure.
|
private ProcedureManager.ProcedureHelper |
pm
Helper to use the ProcedureManager without any context local lookups.
|
private int |
queryDepth
Number of nested queries being processed
|
private long |
scopeTransitions
Counter of the number of scope transitions (push or pop)
|
private ScopedDictionary<OutputTableHandleCopier,java.lang.Integer> |
thOutputParameters
Scoped dictionary which contains the maps of output copiers for a procedure/function to
their 0-based indexes in the set of all TABLE-HANDLE parameters for the procedure/function
(excluding other types of parameters).
|
private long |
transactionCount
Counter of the number of application-level transactions
|
private int |
transactionDepth
Block depth at which full application transaction began, or -1 if not in a transaction
|
private TransactionManager.TransactionHelper |
txHelper
Transaction helper
|
private java.util.Map<Database,BufferManager.TxWrapper> |
txWrapperMap
Database to transaction wrapper instance map
|
private ScopedDictionary<BufferType,BufferManager.UndoData> |
undoData
All undoable actions scoped by block and keyed by buffer type
|
private java.util.Map<RecordBuffer,java.lang.Boolean> |
uninitializedOpenBuffers
Buffers whose scopes have been opened, but are not yet initialized
|
private UniqueTracker.Context |
uniqueTrackerCtx
Context-local access to unique constraint tracker
|
private boolean |
unknownMode
Unknown mode is
true while evaluating query parameters |
private Finalizable |
xactFin
Transaction finalizable to manage transaction state locally (avoid context-local calls)
|
Modifier | Constructor and Description |
---|---|
private |
BufferManager()
Constructor; instances of this class are context-local and must be accessed using the static
get() method. |
Modifier and Type | Method and Description |
---|---|
(package private) java.util.Iterator<RecordBuffer> |
activeBuffers(Persistence persistence)
Get an iterator on all open buffers which contain non-
null
current records for the given persistence object, within the current
client context. |
(package private) java.util.Iterator<RecordBuffer> |
activeBuffers(Persistence persistence,
boolean includeTransient)
Get an iterator on all open buffers which contain non-
null
current records for the given persistence object, within the current
client context. |
(package private) void |
addDirtyBatchBuffer(RecordBuffer buffer)
If we currently are in batch assignment mode, add the given record
buffer to the set of buffers requiring validation at the end of the
batch.
|
(package private) void |
addPendingReclaimedKeys(Persistence persistence,
java.util.List<java.lang.Long> keys)
Add potentially unused keys to be reclaimed after the end of the current transaction or
as buffer scopes are closed after a transaction.
|
(package private) void |
addToAllBuffersArray(int blockDepth,
RecordBuffer buffer)
Add the target buffer to the set of all buffers at the specified block depth.
|
void |
batchNotify(boolean start)
Provides a notification that a batch is starting or ending.
|
void |
beginTx(boolean inTx,
boolean fullTx,
int blockDepth)
Executes logic to explicitly begin a transaction.
|
private void |
bindBuffer(TemporaryBuffer dstBuf,
TemporaryBuffer srcBuf)
Bind the source buffer to the destination.
|
(package private) void |
bufferInitialized(RecordBuffer buffer)
A buffer was initialized.
|
private void |
checkLegacyNames(java.util.Map<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> dst,
java.util.Map<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> src)
Add the source buffers to the destination map.
|
(package private) void |
checkNestedQuery(java.util.function.Supplier<java.lang.Boolean> isFindByRowid)
Check whether the current query depth is non-zero, indicating that we are processing a query within
the context of another query.
|
static void |
cleanupPending()
Cleanup of pending resources.
|
void |
commit(boolean transaction)
A full transaction or sub-transaction is committing.
|
private BufferManager.TxWrapper |
createTxWrapper(Database database)
Create an inactive transaction wrapper for the given database.
|
(package private) boolean |
decrementDepth()
Decrement the query depth.
|
(package private) void |
deregisterBindingBuffer(TemporaryBuffer buf)
Deregister the specified buffer (as it is going out of scope/deleted), from either source
or destination
bindingBuffers . |
(package private) void |
deregisterBindingBuffer(TemporaryBuffer src,
TemporaryBuffer dst,
java.lang.Object referent)
Deregister the source buffer from its DMO-alias binding, in the target referent.
|
(package private) void |
deregisterDynamicBuffer(RecordBuffer buffer,
java.lang.Object referent)
Deregister the given, dynamic record buffer by removing it from the buffer manager's
tracking.
|
(package private) java.util.Set<RecordBuffer> |
endBatchAssignMode()
End batch assignment mode if we are currently in batch assignment mode
and we are in the same scope at which batch assignment mode was
started.
|
void |
endTx(boolean inTx,
boolean fullTx)
Executes logic to explicitly end a transaction.
|
void |
endTxPost()
Executes logic required after a full transaction has ended.
|
(package private) boolean |
evictDMOIfUnused(Persistence persistence,
Persistence.Context local,
Record dmo)
Evict the given DMO from the current ORM session if it is not referenced by any buffer or being
tracked for UNDO purposes.
|
(package private) java.lang.String |
generateUniqueBufferName(java.lang.String legacyBufferName)
Generate unique (across the session) name (DMO alias) for a dynamic buffer.
|
static BufferManager |
get()
Retrieve the context-local instance of this class, instantiating it
first if necessary.
|
int |
getFullTransactionBlock()
Get the zero-based block depth (counting from the outermost scope) at which the current,
full, application-level transaction (if any) began.
|
int |
getOpenBufferScopes()
Query the scope level which currently is open.
|
java.lang.Class<?> |
getPendingBufferClass(RecordBuffer buffer)
Get the defining class for a pending buffer.
|
long |
getScopeTransitions()
Get the number of block scope transitions made.
|
(package private) StaticTempTable |
getStaticTempTable(java.lang.String name)
Get definition for the active static temp table with the given name.
|
(package private) StaticTempTable |
getStaticTempTable(java.lang.String name,
java.lang.Object referent)
Get definition for the active static temp table with the given name.
|
(package private) int |
getStaticTempTableDepth(StaticTempTable stt)
Get the depth of the scope at which the static temp table was opened.
|
(package private) int |
getStaticTempTableDepth(java.lang.String name)
Get the depth of the scope at which the static temp table was opened.
|
(package private) int |
getStaticTempTableDepth(java.lang.String name,
java.lang.Object referent)
Get the depth of the scope at which the static temp table was opened.
|
(package private) long |
getTransactionCount()
Get the current counter value of application-leve transactions which have been opened.
|
(package private) TransactionManager.TransactionHelper |
getTxHelper()
Get the transaction helper object used by this context.
|
(package private) boolean |
incrementDepth()
Increment the query depth.
|
(package private) static void |
initialize()
Register with the
TransactionManager a factory object which creates instances of this
class, so that they can be registered to receive notifications of
runtime scope start and finish events. |
(package private) boolean |
isBatchAssignMode()
Indicate whether we currently are in batch assignment mode.
|
boolean |
isFullTransaction()
Check whether the current block marks (and is within) the boundary of an application-level
full transaction.
|
private boolean |
isImportantBlockTransition()
Indicate whether the current block is "important" from the standpoint of transitioning into
or out of its scope.
|
(package private) boolean |
isNestedQueryError()
Indicate whether a nested query error has been detected and has not yet been cleared.
|
boolean |
isOutputTableHandle(handle h)
Check if the specified handle instance is registered as an OUTPUT argument.
|
boolean |
isTransaction()
Check whether the current block is within an application-level transaction.
|
boolean |
isTransactionAt(int level)
Check whether the block at the specified block depth is within an application-level
transaction.
|
(package private) boolean |
isUnknownMode()
Checks whether the unknown mode is active.
|
(package private) RecordBuffer |
lookupBuffer(java.lang.String alias)
Find the record buffer associated with the given DMO alias.
|
(package private) RecordBuffer |
lookupByName(java.lang.String legacyName)
Find the record buffer associated with the given legacy name, which is the variable name
with which the buffer was defined.
|
(package private) void |
maybeActivateTxWrapper(Database database)
Given a database which has one or more buffers with an open scope operating within an application
level transaction, possibly activate the transaction wrapper associated with that database.
|
private void |
maybeCloseSessions()
Iterate all active persistence contexts and close any open session, if there are no longer
any dependencies on it.
|
private java.lang.String |
message(Persistence persistence,
java.lang.String text)
Compose a message suitable for logging.
|
(package private) void |
notifyRecordWasLoaded(RecordBuffer recordBuffer)
Notify the buffer manager that a new record was loaded (or the old record was reloaded)
into the specified record buffer.
|
(package private) void |
openScope(RecordBuffer buffer)
Called by
RecordBuffer when a new buffer scope is opened. |
(package private) void |
openScopeAt(int openScopeDepth,
RecordBuffer buffer)
Called by
TemporaryBuffer when a new dynamic buffer scope is opened to register the
open scope with the buffer manager, so that the buffer can receive block scope start and
stop notifications, and be registered for commit processing when a full transaction is
begun. |
boolean |
postponeTableHandleDelete(TempTable tempTable)
Marks the table for postponed delete, if it is possible.
|
(package private) void |
reclaimPendingKeys(Persistence persistence,
java.util.Set<java.lang.Long> released)
Reclaim unused keys collected during the transaction which just ended or from the buffer
scope which just closed.
|
(package private) boolean |
registerBindingBuffer(TemporaryBuffer dstBuf,
TemporaryBuffer srcBuf)
Register a buffer which is binding to the specified destination.
|
(package private) void |
registerBuffer(RecordBuffer buffer)
Register a newly defined record buffer in the current scope.
|
(package private) void |
registerBufferUndoable(RecordBuffer buffer,
Undoable undoTarget)
Register an undoable which is responsible for setting the buffer's
proper current record after all reversibles are processed.
|
void |
registerDirtyBuffer(RecordBuffer recordBuffer)
Register this buffer as 'dirty' in the current scope.
|
(package private) void |
registerOutputTableHandleCopier(OutputTableHandleCopier copier)
Register the output table copier.
|
(package private) void |
registerPending(java.lang.Class<?> def,
RecordBuffer buffer)
Register as pending the newly defined record buffer.
|
void |
registerPendingBufferClass(RecordBuffer buffer,
java.lang.Class<?> cls)
Register a pending buffer's defining class.
|
(package private) void |
registerPendingStaticTempTable(StaticTempTable table,
boolean global)
Register static temp table, when the external program gets executed.
|
(package private) void |
registerPersistenceContext(Persistence.Context pc)
Register an active persistence context, indicating a database session has been opened.
|
(package private) void |
registerStaticTempTable(StaticTempTable table,
boolean global)
Register static temp-table when its scope is opened.
|
(package private) void |
removeAllReversibles(TemporaryBuffer buffer)
Remove all
Reversible objects associated with the given buffer from their
respective scoped dictionaries. |
void |
resetState(boolean clearOnly)
Releases the buffers into which a new record was loaded (or the old
record was reloaded) into the current or deeper scopes, or only clears
the list of buffers pending to be released.
|
void |
resolvePendingBufferClasses(java.lang.Object referent)
Resolve the defining Java class for all Java fields which define a buffer.
|
void |
rollback(boolean transaction)
A full transaction or sub-transaction is rolling back.
|
void |
scopeDeleted()
Provides notification that the external procedure scope has been deleted.
|
void |
scopeFinished()
Process a notification that a scope is about to be exited.
|
void |
scopeStart()
Process a notification that a new block scope has been entered.
|
(package private) java.lang.Runnable |
setUnknownMode(boolean unknownMode)
Changes the unknown mode.
|
(package private) void |
startBatchAssignMode(boolean internal)
Begin batch assignment mode.
|
private void |
trackDatabase(RecordBuffer buffer,
boolean add)
Track the buffer's database.
|
(package private) void |
unregisterOutputTableHandleCopier(OutputTableHandleCopier copier)
Unregister the output table copier in the current scope.
|
void |
validate(boolean transaction,
boolean aggressiveFlush)
A block is exiting or iterating normally within a transaction.
|
boolean |
vetoStop(StopConditionException exc)
Check the specified exception and determine whether we want to allow it
to be honored by the
TransactionManager , or whether we want to
veto the STOP at this scope. |
private static final java.util.logging.Logger LOG
private static final ContextLocal<BufferManager> context
private static boolean initialized
initialize()
was calledprivate static final java.util.Map<java.lang.Class<?>,java.util.Set<java.lang.reflect.Field>> classBufferFields
final java.util.Map<BufferType,MutableInteger> changeScopes
private final Finalizable xactFin
private final Finalizable batchCleaner
private final Scopeable fieldScopes
private final java.util.Set<RecordBuffer> pendingBuffers
private final java.util.Map<RecordBuffer,java.lang.Class<?>> pendingBufferClasses
private final ScopedDictionary<java.lang.String,RecordBuffer> allBuffers
private final ScopedDictionary<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> byLegacyName
Note: only the static buffers are kept in this structure. The dynamic resources cannot be stored here as their NAME attribute is mutable and will possible collide with other existing buffers.
private final ScopedDictionary<RecordBuffer,java.lang.Boolean> loadedBuffers
private final java.util.Map<RecordBuffer,java.lang.Boolean> uninitializedOpenBuffers
private final ScopedList<RecordBuffer> openBuffers
private final ScopedDictionary<RecordBuffer,java.lang.Boolean> dirtyBuffers
committed
or rolled back
, then the buffers will be merged
in the previous scope.private final ScopedDictionary<BufferManager.TempTableKey,StaticTempTable> openStaticTempTables
TempTableKey
compound from the legacy table
name and the procedure where the temp table was defined.private final java.util.Map<StaticTempTable,java.lang.Boolean> pendingStaticTempTables
private final ScopedDictionary<OutputTableHandleCopier,java.lang.Integer> thOutputParameters
private final java.util.Map<Database,BufferManager.TxWrapper> txWrapperMap
private final java.util.Map<Database,BufferManager.TxWrapper> inactiveTxWrappers
private final java.util.Set<Persistence.Context> activePersistenceContexts
private final ScopedDictionary<BufferType,BufferManager.UndoData> undoData
private final java.util.ArrayDeque<BufferManager.BatchModeData> batchModeStack
private final java.util.Map<java.lang.Object,BufferManager.PersistentProcScope> persistProcScopes
private final java.util.Map<Persistence,java.util.Set<java.lang.Long>> pendingReclaimedKeys
private final ProcedureManager.ProcedureHelper pm
private final java.util.Map<Database,MutableInteger> activeDatabases
private final TransactionManager.TransactionHelper txHelper
private int transactionDepth
private ConnectionManager connMgr
private UniqueTracker.Context uniqueTrackerCtx
private int queryDepth
private long scopeTransitions
private long transactionCount
private java.util.Map<TemporaryBuffer,java.util.Map<java.lang.Object,java.util.Set<TemporaryBuffer>>> bindingBuffers
private boolean unknownMode
true
while evaluating query parametersprivate boolean nestedQueryError
private BufferManager()
get()
method.public static BufferManager get()
java.lang.IllegalStateException
- when BufferManager
is not activated, i.e. initialize()
is not called.public static void cleanupPending()
static void initialize()
TransactionManager
a factory object which creates instances of this
class, so that they can be registered to receive notifications of
runtime scope start and finish events.
This method should be invoked once during the server bootstrap phase.
public void registerDirtyBuffer(RecordBuffer recordBuffer)
This registration doesn't mean that at the time of commit(boolean)
, rollback(boolean)
, or
validate(boolean, boolean)
the buffer's record is still 'dirty' - this is used to limit the set of buffers
receiving such notifications, to avoid iterating over all openBuffers
.
recordBuffer
- The record buffer.public void registerPendingBufferClass(RecordBuffer buffer, java.lang.Class<?> cls)
buffer
- The newly constructed buffer instance.cls
- The Java class associated with an external program or legacy OE class, where it
was defined.public java.lang.Class<?> getPendingBufferClass(RecordBuffer buffer)
buffer
- The newly constructed buffer instance.public void resolvePendingBufferClasses(java.lang.Object referent)
referent
- The instance associated with an external program or legacy OE class.public void commit(boolean transaction)
commit
in interface Commitable
transaction
- true
if full transaction; false
if sub-transaction.public void rollback(boolean transaction)
rollback
in interface Commitable
transaction
- true
if full transaction; false
if sub-transaction.public void validate(boolean transaction, boolean aggressiveFlush)
validate
in interface Commitable
transaction
- true
if full transaction; false
if sub-transaction.aggressiveFlush
- true
if transaction manager is in aggressive subtransaction
flush mode, indicating that any transient buffers should be validated and
flushed, regardless of other state.public int getOpenBufferScopes()
TransactionManager
.public boolean vetoStop(StopConditionException exc)
TransactionManager
, or whether we want to
veto the STOP at this scope.
This implementation is interested only in STOP conditions which have
been generated by database connection errors. STOP processing at the
current scope is vetoed iff the exception is an instance of DatabaseConnectionException
AND either of the following criteria are
met:
Otherwise, normal STOP processing is allowed to continue.
vetoStop
in interface StopConditionVetoHandler
exc
- The exception to be checked.true
if STOP should be vetoed;
false
if the STOP should be allowed.public void beginTx(boolean inTx, boolean fullTx, int blockDepth)
inTx
- Flag indicating if we are in a transaction.fullTx
- Flag indicating if we are in a full transaction.blockDepth
- The current block depth (all blocks tracked by the TransactionManager
).public void endTx(boolean inTx, boolean fullTx)
inTx
- Flag indicating if we are in a transaction.fullTx
- Flag indicating if we are in a full transaction.public void endTxPost()
public void scopeStart()
scopeStart
in interface Scopeable
ErrorConditionException
- if there is an error flushing pending changes to the database
as we open a new database transaction.public void scopeFinished()
scopeFinished
in interface Scopeable
public void scopeDeleted()
If we are deleting a persistent procedure, clean all its data from the global scope for the
following dictionaries: loadedBuffers
, openBuffers
, allBuffers
,
openStaticTempTables
.
scopeDeleted
in interface Scopeable
public void batchNotify(boolean start)
start
.batchNotify
in interface BatchListener
start
- true
if this is the start of a batch, otherwise
false
.RecordBuffer.startBatch(boolean)
,
RecordBuffer.endBatch(boolean)
public void resetState(boolean clearOnly)
resetState
in interface Resettable
clearOnly
- If true
then clear the list of buffers pending to be
released, otherwise perform release of these buffers and clear
the list after that.public boolean postponeTableHandleDelete(TempTable tempTable)
tempTable
- Temporary table to be marked for postponed delete.true
if the table was postponed for deletion. false
if
this can't be done.public boolean isTransaction()
true
if we are in a transaction, else false
.public boolean isTransactionAt(int level)
level
- Zero-based block depth (counting from the outermost scope).true
if we are in a transaction, else false
.public boolean isFullTransaction()
true
if we are at (and within) a full transaction boundary, else false
.public int getFullTransactionBlock()
public long getScopeTransitions()
long getTransactionCount()
boolean registerBindingBuffer(TemporaryBuffer dstBuf, TemporaryBuffer srcBuf)
Whenever the current ProcedureManager.thisProcedure()
is entering and exiting a
top-level scope, the destination buffer will have its DMO alias set to the source buffer.
TODO: currently we don't support a buffer to be bound to more than one destination, in the same 4GL external program.
dstBuf
- The destination buffer.srcBuf
- The source buffer.true
if the source buffer's DMO alias was changed.void deregisterBindingBuffer(TemporaryBuffer buf)
bindingBuffers
.buf
- The buffer to deregister.void deregisterBindingBuffer(TemporaryBuffer src, TemporaryBuffer dst, java.lang.Object referent)
src
- The source buffer.dst
- The destination buffer.referent
- The external program instance.private void bindBuffer(TemporaryBuffer dstBuf, TemporaryBuffer srcBuf)
dstBuf
- The destination buffer.srcBuf
- The source buffer.TransactionManager.TransactionHelper getTxHelper()
void registerPersistenceContext(Persistence.Context pc)
pc
- Persistence context.void registerBufferUndoable(RecordBuffer buffer, Undoable undoTarget)
buffer
- Record buffer for which a change is being tracked for undo
purposes. It is assumed the buffer has been initialized.undoTarget
- The undoable responsible with setting the buffer back to its
proper record.void registerBuffer(RecordBuffer buffer)
buffer
- Buffer to be registered.void registerPending(java.lang.Class<?> def, RecordBuffer buffer)
pendingBuffers
will be registered with
that scope. Buffers are deregistered implicitly when the scope in which
they were registered ends.def
- The Java class defining this buffer.buffer
- Buffer pending to be registered.void deregisterDynamicBuffer(RecordBuffer buffer, java.lang.Object referent)
buffer
- Dynamic record buffer to be removed.referent
- The persistent procedure where the buffer was defined; may be null
.void startBatchAssignMode(boolean internal)
internal
- Use false
for a programmer required batch assign mode. These can be started at most one
at each scope depth.true
for a FWD internal maintenance batch block when some data must be processed
"in batch". In this case the depth, is not checked. Only one level of this can be added as the
top-level. This mode must be be ended before starting any new batch.java.lang.IllegalStateException
- if batch mode is already active in the current block or was started but never
ended in a previous block.RecordBuffer.startBatch(boolean)
,
RecordBuffer.endBatch(boolean)
,
RecordBuffer.cleanupBatchMode(com.goldencode.p2j.persist.BufferManager)
java.util.Set<RecordBuffer> endBatchAssignMode()
null
, indicating
either we are not in batch mode, or we are not in the proper
scope to end it, or the buffers already have been processed, or
the program is ending and we are in cleanup mode.RecordBuffer.startBatch(boolean)
,
RecordBuffer.endBatch(boolean)
,
RecordBuffer.cleanupBatchMode(com.goldencode.p2j.persist.BufferManager)
boolean isBatchAssignMode()
true
if in batch assignment mode, else
false
.startBatchAssignMode(boolean)
,
endBatchAssignMode()
void addDirtyBatchBuffer(RecordBuffer buffer)
buffer
- Buffer to be added to the set of dirty batch mode buffers.startBatchAssignMode(boolean)
,
endBatchAssignMode()
boolean incrementDepth()
This method MUST be invoked in balanced pairs that involve a subsequent call to
decrementDepth()
. Calls may be nested, but they must be balanced, such that
at the end of all nested calls, queryDepth
must be 0
.
true
if the starting depth is 0.boolean decrementDepth()
This method MUST be invoked in balanced pairs that involve a subsequent call to
incrementDepth()
. Calls may be nested, but they must be balanced, such that
at the end of all nested calls, queryDepth
must be 0
.
true
if the resulting depth is 0.void checkNestedQuery(java.util.function.Supplier<java.lang.Boolean> isFindByRowid)
isFindByRowid
- A lambda expression which should return true
if the current database operation
represents a legacy FIND by RECID/ROWID, else false
.boolean isNestedQueryError()
true
if a nested query error has been detected, else false
.java.lang.Runnable setUnknownMode(boolean unknownMode)
unknownMode
- The new unknown mode.Runnable
which should be called in a finally
block, paired with the call to
this method, which restores the unknown mode to its previous value.boolean isUnknownMode()
void addPendingReclaimedKeys(Persistence persistence, java.util.List<java.lang.Long> keys)
persistence
- Persistence helper object for a particular database.keys
- Keys to be reclaimed.void reclaimPendingKeys(Persistence persistence, java.util.Set<java.lang.Long> released)
persistence
- Persistence helper object for a particular database.released
- Keys actually released, due to the corresponding locks on them being released
(as opposed to downgraded).void removeAllReversibles(TemporaryBuffer buffer)
Reversible
objects associated with the given buffer from their
respective scoped dictionaries.buffer
- Buffer associated with the Reversible
s to be removed.void openScope(RecordBuffer buffer)
RecordBuffer
when a new buffer scope is opened. It registers the open scope with the
buffer manager, so that the buffer can receive block scope start and stop notifications, and be
registered for commit/rollback/validate processing when a full transaction is begun.buffer
- Buffer for which a new scope is being opened.void registerStaticTempTable(StaticTempTable table, boolean global)
table
- The static temp-table.global
- Indicates if it is a global temp-table (declared as SHARED GLOBAL).void registerPendingStaticTempTable(StaticTempTable table, boolean global)
table
- The static temp-table.global
- Indicates if it is a global temp table (declared as SHARED GLOBAL).public boolean isOutputTableHandle(handle h)
h
- The handle instance.true
if the handle originates from the caller as an OUTPUT argument.void registerOutputTableHandleCopier(OutputTableHandleCopier copier)
copier
- Copier to register.void unregisterOutputTableHandleCopier(OutputTableHandleCopier copier)
copier
- Copier to unregister.StaticTempTable getStaticTempTable(java.lang.String name)
name
- Legacy name of the target static temp table.null
if
there is no active table with the given name.StaticTempTable getStaticTempTable(java.lang.String name, java.lang.Object referent)
name
- Legacy name of the target static temp table.referent
- The external program where it was defined.null
if
there is no active table with the given name.int getStaticTempTableDepth(java.lang.String name)
name
- Legacy name of the target static temp table.-1
is returned.int getStaticTempTableDepth(StaticTempTable stt)
stt
- The static temp-table instance.-1
is returned.int getStaticTempTableDepth(java.lang.String name, java.lang.Object referent)
name
- Legacy name of the target static temp table.referent
- The external program where it was defined.-1
is returned.void addToAllBuffersArray(int blockDepth, RecordBuffer buffer)
blockDepth
- Zero-based depth of the block (starting from the outermost block) at which the
buffer was opened.buffer
- Buffer to add.void openScopeAt(int openScopeDepth, RecordBuffer buffer)
TemporaryBuffer
when a new dynamic buffer scope is opened to register the
open scope with the buffer manager, so that the buffer can receive block scope start and
stop notifications, and be registered for commit processing when a full transaction is
begun.openScopeDepth
- Zero-based depth of the open scopes (starting from the outermost scope) at which this
buffer scope is opened.buffer
- Buffer for which a new scope is being opened.void bufferInitialized(RecordBuffer buffer)
buffer
- Record buffer which was initialized.void maybeActivateTxWrapper(Database database)
If the transaction wrapper for the given database already is active, do nothing.
database
- Database with at least one buffer with an open scope.RecordBuffer lookupBuffer(java.lang.String alias)
alias
- Buffer DMO alias in business logic. (AKA Java name)null
if not found.RecordBuffer lookupByName(java.lang.String legacyName)
pendingBuffers
.legacyName
- Buffer variable's legacy name in business logic.null
if not found.java.util.Iterator<RecordBuffer> activeBuffers(Persistence persistence)
null
current records for the given persistence object, within the current
client context. Auto-commit record buffers associated with a pending,
reversible rollback are not included in the iteration. Records that
represent copies of DMOs from other sessions, obtained from a DirtyShareContext
, are likewise excluded.persistence
- Persistence object which manages sessions. Only record
buffers associated with this persistence object are returned.java.util.Iterator<RecordBuffer> activeBuffers(Persistence persistence, boolean includeTransient)
null
current records for the given persistence object, within the current
client context. Auto-commit record buffers associated with a pending,
reversible rollback are not included in the iteration. Records that
represent copies of DMOs from other sessions, obtained from a DirtyShareContext
, are likewise excluded.persistence
- Persistence object which manages sessions. Only record
buffers associated with this persistence object are returned.includeTransient
- true
to include transient records in the result set.boolean evictDMOIfUnused(Persistence persistence, Persistence.Context local, Record dmo) throws PersistenceException
persistence
- Persistence object which manages sessions.local
- Current user persistence context.dmo
- DMO instance whose reference count is to be decremented.true
if the DMO was evicted; false
if it was in use.PersistenceException
- if an error occurs detaching dmo
from the persistence session.void notifyRecordWasLoaded(RecordBuffer recordBuffer)
recordBuffer
- The record buffer in which a record was loaded (or the old record was reloaded).java.lang.String generateUniqueBufferName(java.lang.String legacyBufferName)
__{unique number}
postfix. This guarantees that the name will not contain
invalid characters and will be unique.legacyBufferName
- Legacy name of the buffer.private void maybeCloseSessions()
private BufferManager.TxWrapper createTxWrapper(Database database)
database
- Database for which this transaction wrapper is created.private java.lang.String message(Persistence persistence, java.lang.String text)
persistence
- Persistence object which will provide context info.text
- Custom message text.private void checkLegacyNames(java.util.Map<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> dst, java.util.Map<java.lang.Object,java.util.Map<java.lang.String,RecordBuffer>> src)
dst
- The destination map.src
- The source map.private void trackDatabase(RecordBuffer buffer, boolean add)
activeDatabases
counter when a new buffer
is activated, and decrement it when it exists its scope.buffer
- The buffer to track.add
- Flag indicating if the buffer is opening or closing the scope.java.lang.IllegalStateException
- If we are removing an active buffer and there is no entry for it in activeDatabases
.private boolean isImportantBlockTransition()
This notion of importance is used to determine whether the various scoped data structures managed by this class need to add or delete a scope when transitioning into or out of the block, respectively, and whether we need to perform processing (e.g., copying/moving data between scopes) associated with such transitions.
true
if the block is considered "important" by the above criteria, else
false
.