|
|||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||
java.lang.Object | +--arlut.csd.ganymede.DBEditSet
DBEditSet is the basic transactional unit. All changes to the
database during normal operations are made in the context of a
DBEditSet, which may then be committed or rolled back as an atomic
operation. Each DBSession will
have at most one DBEditSet transaction object active at any time.
A DBEditSet tracks several things for the server, including instances of
DBEditObject's that were created
or checked-out from the DBStore,
DBNameSpace values that were reserved
during the course of the transaction, and DBLogEvent
objects to be recorded in the DBLog and/or
mailed out to various interested parties when the transaction is committed.
DBEditSet's transaction logic is based on a two-phase commit
protocol, where all DBEditObject's involved in the transaction are
given an initial opportunity to approve or reject the transaction's
commit before the DBEditSet commit method goes back and 'locks-in'
the changes. DBEditObjects are able to initiate changes external
to the Ganymede database in their
commitPhase2()
methods, if needed.
When a DBEditSet is committed, a DBWriteLock
is established on all DBObjectBase's
involved in the transaction. All objects checked out by that transaction
are then updated in the DBStore, and a summary of changes is recorded to the
DBStore DBJournal. The database as
a whole will not be dumped to disk unless and until the
dumpTask is run, or until the server
undergoes a formal shutdown.
Typically, the commit()
method is called by the
GanymedeSession.commitTransaction()
method, which will induce the server to schedule any commit-time build
tasks registered with the GanymedeScheduler.
If a DBEditSet commit() operation fails catastrophically, or if
release() is called,
all DBEditObjects created or checked out during the course of the
transaction will be discarded, all DBNameSpace values allocated will
be relinquished, and any logging information for the abandoned transaction
will be forgotten.
As if all that wasn't enough, the DBEditSet class also maintains a stack
of DBCheckPoint objects to enable
users to set checkpoints during the course of a transaction. These objects
are basically a snapshot of the transaction's state at the moment of the
checkpoint, and are used to rollback the transaction to a known state if
a series of linked operations within a transaction cannot all be completed.
Finally, note that the DBEditSet class does not actually track namespace value allocations.. instead, the DBNameSpace class is responsible for recording a list of values allocated by each active DBEditSet. When a DBEditSet commits or releases, all DBNameSpace objects in the server are informed of this, whereupon they do their own cleanup.
| Field Summary | |
private java.util.Hashtable |
basesModified
A record of the DBObjectBase's
touched by this transaction. |
(package private) NamedStack |
checkpoints
A stack of DBCheckPoint objects
to keep track of check points performed during the course of this transaction. |
(package private) java.lang.Thread |
currentCheckpointThread
We keep track of the thread that is doing checkpointing.. |
(package private) DBStore |
dbStore
Who's our daddy? |
(package private) static boolean |
debug
|
(package private) java.lang.String |
description
A brief description of the client associated with this transaction, used in logging to identify what was done by the main client, what by a password-changing utility, etc. |
private boolean |
interactive
True if this DBEditSet is operating in interactive mode. |
(package private) java.util.Vector |
logEvents
A list of DBLogEvent's
to be written to the Ganymede logfile and/or mailed out when
this transaction commits. |
private boolean |
mustAbort
True if this DBEditSet is operating in non-interactive mode and a rollback was ordered. |
(package private) java.util.Hashtable |
objects
A hashtable mapping Invids to DBEditObjects checked out in
care of this transaction. |
(package private) DBSession |
session
A reference to the DBSession that this transaction is attached to. |
(package private) DBWriteLock |
wLock
The writelock acquired during the course of a commit attempt. |
| Constructor Summary | |
DBEditSet(DBStore dbStore,
DBSession session,
java.lang.String description,
boolean interactive)
Constructor for DBEditSet |
|
| Method Summary | |
boolean |
addObject(DBEditObject object)
Method to associate a DBEditObject with this transaction. |
void |
checkpoint(java.lang.String name)
This method checkpoints the current transaction at its current state. |
ReturnVal |
commit()
commit is used to cause all changes in association with this DBEditSet to be performed. |
DBEditObject |
findObject(DBObject object)
Method to find a DBObject / DBEditObject if it has previously been checked out to this EditSet in some fashion. |
DBEditObject |
findObject(Invid invid)
Method to find a DBObject / DBEditObject if it has previously been checked out to this EditSet in some fashion. |
DBSession |
getSession()
Method to return the DBSession handle owning this transaction. |
boolean |
isInteractive()
|
void |
logEvent(DBLogEvent event)
This method is used to register a log event with this transaction. |
void |
logEvent(java.lang.String eventClassToken,
java.lang.String description,
Invid admin,
java.lang.String adminName,
java.util.Vector objects,
java.util.Vector notifyList)
This method is used to register a log event with this transaction. |
void |
logMail(java.util.Vector addresses,
java.lang.String subject,
java.lang.String message)
This method is used to record a message to be sent out when the transaction is committed. |
void |
logMail(java.util.Vector addresses,
java.lang.String subject,
java.lang.String message,
Invid admin,
java.lang.String adminName,
java.util.Vector objects)
This method is used to record a message to be sent out when the transaction is committed. |
DBCheckPoint |
popCheckpoint(java.lang.String name)
This method is used to pop a checkpoint off the checkpoint stack. |
DBCheckPoint |
popCheckpoint(java.lang.String name,
boolean inRollback)
This method is used to pop a checkpoint off the checkpoint stack. |
void |
release()
release is used to abandon all changes made in association with this DBEditSet. |
private void |
releaseWriteLock(java.lang.String reason)
This is a dinky little private helper method to keep things clean. |
boolean |
rollback(java.lang.String name)
This brings this transaction back to the state it was at at the time of the matching checkPoint() call. |
private void |
syncObjBackPointers(DBEditObject obj)
This method is executed towards the end of a transaction commit, and compares the current state of this object with its original state, and makes the appropriate changes to the backPointers hash in
the server's DBStore object. |
| Methods inherited from class java.lang.Object |
|
| Field Detail |
static final boolean debug
java.util.Hashtable objects
DBEditObjects checked out in
care of this transaction.java.util.Vector logEvents
DBLogEvent's
to be written to the Ganymede logfile and/or mailed out when
this transaction commits.private java.util.Hashtable basesModified
A record of the DBObjectBase's
touched by this transaction. These DBObjectBase's will be locked
when this transaction is committed.
DBStore dbStore
DBSession session
java.lang.String description
NamedStack checkpoints
DBCheckPoint objects
to keep track of check points performed during the course of this transaction.java.lang.Thread currentCheckpointThread
We keep track of the thread that is doing checkpointing.. once a thread starts a checkpoint on this transaction, we don't allow any other threads to checkpoint until the first thread releases its checkpoint. This is to prevent problems resulting from interleaved checkpoint/popCheckpoint/rollback activities across multiple threads.
DBWriteLock wLock
releaseWriteLock()
method, but wLock should really never be non-null outside of the
context of the commit() call.private boolean interactive
True if this DBEditSet is operating in interactive mode.
private boolean mustAbort
True if this DBEditSet is operating in non-interactive mode and a rollback was ordered. In such cases, the server skipped doing the checkpoint and so has no choice but to condemn the whole transaction.
| Constructor Detail |
public DBEditSet(DBStore dbStore,
DBSession session,
java.lang.String description,
boolean interactive)
dbStore - The owning DBStore object.session - The DBStore session owning this transaction.description - An optional string to identify this transactioninteractive - If false, this transaction will operate in
non-interactive mode. Certain Invid operations will be optimized
to avoid doing choice list queries and bind checkpoint
operations. When a transaction is operating in non-interactive mode,
any failure that cannot be handled cleanly due to the optimizations will
result in the transaction refusing to commit when commitTransaction()
is attempted. This mode is intended for batch operations.| Method Detail |
public DBSession getSession()
Method to return the DBSession handle owning this transaction.
public boolean isInteractive()
public DBEditObject findObject(DBObject object)
Method to find a DBObject / DBEditObject if it has previously been checked out to this EditSet in some fashion.
public DBEditObject findObject(Invid invid)
Method to find a DBObject / DBEditObject if it has previously been checked out to this EditSet in some fashion. This method is used to allow consistency check code in the DBEditObjects to get a transaction consistent view of the system as it stands with the transaction's changes made.
public boolean addObject(DBEditObject object)
Method to associate a DBEditObject with this transaction.
This method is called by the createDBObject and editDBObject
methods in DBSession.
object - The newly created DBEditObject.
public void logEvent(java.lang.String eventClassToken,
java.lang.String description,
Invid admin,
java.lang.String adminName,
java.util.Vector objects,
java.util.Vector notifyList)
This method is used to register a log event with this transaction. If the transaction successfully commits, the provided log event will be recorded in the Ganymede log file and mail notification will be sent out if appropriate.
eventClassToken - a short string specifying a DBObject record describing
the general category for the eventdescription - Descriptive text to be entered in the record of the eventadmin - Invid pointing to the adminPersona that fired the event, if anyadminName - String containing the name of the adminPersona that fired the event, if anyobjects - A vector of invids of objects involved in this event.notifyList - A vector of Strings listing email addresses to send notification
of this event to.public void logEvent(DBLogEvent event)
This method is used to register a log event with this transaction. If the transaction successfully commits, the provided log event will be recorded in the Ganymede log file and mail notification will be sent out if appropriate.
event - A pre-formed log event to register with this transaction.
public void logMail(java.util.Vector addresses,
java.lang.String subject,
java.lang.String message,
Invid admin,
java.lang.String adminName,
java.util.Vector objects)
addressList - Vector of Strings, the address listsubject - The subject line of the messagemessage - The body of the messageadmin - The invid of the admin whose action resulted in the mailadminName - The name of the admin whose actin resulted in the mailobjects - A vector of invids of objects involved in the mail
public void logMail(java.util.Vector addresses,
java.lang.String subject,
java.lang.String message)
addressList - Vector of Strings, the address listsubject - The subject line of the messagemessage - The body of the messagepublic void checkpoint(java.lang.String name)
This method checkpoints the current transaction at its current state. If need be, this transaction can later be rolled back to this point by calling the rollback() method.
Once a thread checkpoints a transaction, no other thread can checkpoint a transaction until some thread clears the checkpoint, either by doing a rollback() or a popCheckpoint(). checkpoint() will block any threads that try to establish a checkpoint() until the prior thread's checkpoint is resolved.
See DBSession.deleteDBObject() and DBSesssion.createDBObject() for instances of this.
name - An identifier for this checkpointpublic DBCheckPoint popCheckpoint(java.lang.String name)
This method is used to pop a checkpoint off the checkpoint stack. This method is equivalent to a rollback where the checkpoint information is taken off the stack, but this DBEditSet's state is not reverted.
Any checkpoints that were placed on the stack after the checkpoint matching <name> will also be removed from the checkpoint stack.
name - An identifier for the checkpoint to take off
the checkpoint stack.
public DBCheckPoint popCheckpoint(java.lang.String name,
boolean inRollback)
This method is used to pop a checkpoint off the checkpoint stack. This method is equivalent to a rollback where the checkpoint information is taken off the stack, but this DBEditSet's state is not reverted.
Any checkpoints that were placed on the stack after the checkpoint matching <name> will also be removed from the checkpoint stack.
name - An identifier for the checkpoint to take off
the checkpoint stack.inRollback - If true, popCheckpoint will not actually
pop the checkpoint states out of the DBStore namespaces,
leaving that for rollback() to finish up.public boolean rollback(java.lang.String name)
This brings this transaction back to the state it was at at the time of the matching checkPoint() call. Any objects that were checked out in care of this transaction since the checkPoint() will be checked back into the database and made available for other transactions to access. All namespace changes made by this transaction will likewise be rolled back to their state at the checkpoint.
name - An identifier for the checkpoint to be rolled back to.public ReturnVal commit()
commit is used to cause all changes in association with this DBEditSet to be performed. If commit() cannot make the changes for any reason, commit() will return a ReturnVal indicating failure and the cause of the commit failure, and will leave the transaction open for a subsequent commit() attempt, or an abort().
The returned ReturnVal
will have doNormalProcessing set to false if the transaction was
completely aborted. Both DBSession and the client should take a false doNormalProcessing
boolean as an indicator that the transaction was simply wiped out
and a new transaction should be opened for subsequent activity.
A true doNormalProcessing value indicates that the client can try
the commit again at a later time, or manually cancel.
This method is synchronized and calls a synchronized method on the DBSession which contains this DBEditSet. Because of this, this method should really only be called by way of the DBSession.commitTransaction() method, to avoid the possibility of nested monitor deadlock.
private void syncObjBackPointers(DBEditObject obj)
This method is executed towards the end of a transaction commit,
and compares the current state of this object with its original state,
and makes the appropriate changes to the
backPointers hash in
the server's DBStore object.
The purpose of this is to support the decoupling of an object from its backlinks, so that objects can be asymmetrically linked to an object without having to check that object out for editing.
public void release()
release is used to abandon all changes made in association with this DBEditSet. All DBObjects created, deleted, or modified, and all unique values allocated and freed during the course of actions on this transaction will be reverted to their state when this transaction was created.
Note that this does not mean that the entire DBStore will revert to its state at the beginning of this transaction; any changes not relating to objects and namespace values connected to this transaction will not be affected by this transaction's release.
private void releaseWriteLock(java.lang.String reason)
This is a dinky little private helper method to keep things clean. It's essential that wLock be released if things go wrong, else next time this session tries to commit a transaction, it'll wind up waiting forever for the old lock to be released.
|
|||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||